diff --git a/output/fceux.chm b/output/fceux.chm index 56c19504..ccba53ee 100644 Binary files a/output/fceux.chm and b/output/fceux.chm differ diff --git a/output/taseditor.chm b/output/taseditor.chm index c0318726..aed0c445 100644 Binary files a/output/taseditor.chm and b/output/taseditor.chm differ diff --git a/vc/Help/fceux.hnd b/vc/Help/fceux.hnd index 11113601..4131cbed 100644 Binary files a/vc/Help/fceux.hnd and b/vc/Help/fceux.hnd differ diff --git a/vc/Help/readme.txt b/vc/Help/readme.txt index e4deb0c5..7cf41f2e 100644 --- a/vc/Help/readme.txt +++ b/vc/Help/readme.txt @@ -1,6 +1,10 @@ -This .hnd files are used to create documentation. -Made with HelpNDoc v3.0 Freeware Version. +These .hnd files are used to create documentation. +Originally made with HelpNDoc v3.0 Freeware Version. +fceux.hnd has been updated to HelpNDoc v7.0 format (no longer compatible with v3) +taseditor.hnd has been updated to HelpNDoc v7.0 format + +taseditor-ru.hnd is assumed to be still be v3.0 After compiling the docs into CHM/HTML format, you should do the following: diff --git a/vc/Help/taseditor.hnd b/vc/Help/taseditor.hnd index 3cf0b3f2..ca46ac21 100644 Binary files a/vc/Help/taseditor.hnd and b/vc/Help/taseditor.hnd differ diff --git a/web/help/6502CPU.html b/web/help/6502CPU.html index 820868f9..29d99b7e 100644 --- a/web/help/6502CPU.html +++ b/web/help/6502CPU.html @@ -1,1612 +1,1803 @@ - - + + + + + - CPU - 6502 - - - - - - - - - - + + + + + + + + CPU - 6502 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

CPU - 6502

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

#

-

# $Id: 6502_cpu.txt,v 1.1.1.1 2004/08/29 01:29:35 bryan Exp $

-

#

-

# This file is part of Commodore 64 emulator

-

#      and Program Development System.

-

#

-

# See README for copyright notice

-

#

-

# This file contains documentation for 6502/6510/8500/8502 instruction set.

-

#

-

#

-

# Written by

-

#   John West       (john@ucc.gu.uwa.edu.au)

-

#   Marko MЉkelЉ    (msmakela@kruuna.helsinki.fi)

-

#

-

#

-

# $Log: 6502_cpu.txt,v $

-

# Revision 1.1.1.1  2004/08/29 01:29:35  bryan

-

# no message

-

#

-

# Revision 1.1  2002/05/21 00:42:27  xodnizel

-

# updates

-

#

-

# Revision 1.8  1994/06/03  19:50:04  jopi

-

# Patchlevel 2

-

#

-

# Revision 1.7  1994/04/15  13:07:04  jopi

-

# 65xx Register descriptions added

-

#

-

# Revision 1.6  1994/02/18  16:09:36  jopi

-

#

-

# Revision 1.5  1994/01/26  16:08:37  jopi

-

# X64 version 0.2 PL 1

-

#

-

# Revision 1.4  1993/11/10  01:55:34  jopi

-

#

-

# Revision 1.3  93/06/21  13:37:18  jopi

-

#  X64 version 0.2 PL 0

-

#

-

# Revision 1.2  93/06/21  13:07:15  jopi

-

# *** empty log message ***

-

#

-

#

-


-

Note: To extract the uuencoded ML programs in this article most

-

      easily you may use e.g. "uud" by Edwin Kremer ,

-

      which extracts them all at once.

-


-


-

Documentation for the NMOS 65xx/85xx Instruction Set

-


-

       6510 Instructions by Addressing Modes

-

       6502 Registers

-

       6510/8502 Undocumented Commands

-

       Register selection for load and store

-

       Decimal mode in NMOS 6500 series

-

       6510 features

-

       Different CPU types

-

       6510 Instruction Timing

-

       How Real Programmers Acknowledge Interrupts

-

       Memory Management

-

       Autostart Code

-

       Notes

-

       References

-


-


-

6510 Instructions by Addressing Modes

-


-

off- ++++++++++ Positive ++++++++++  ---------- Negative ----------

-

set  00      20      40      60      80      a0      c0      e0      mode

-


-

+00  BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX     Impl/immed

-

+01  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir,x)

-

+02   t       t       t       t      NOP*t   LDX     NOP*t   NOP*t     ? /immed

-

+03  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    (indir,x)

-

+04  NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX     Zeropage

-

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

-

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

-

+07  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Zeropage

-


-

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

-

+09  ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC     Immediate

-

+0a  ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP     Accu/impl

-

+0b  ANC**   ANC**   ASR**   ARR**   ANE**   LXA**   SBX**   SBC*    Immediate

-

+0c  NOP*    BIT     JMP     JMP ()  STY     LDY     CPY     CPX     Absolute

-

+0d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute

-

+0e  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Absolute

-

+0f  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Absolute

-


-

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

-

+11  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir),y

-

+12   t       t       t       t       t       t       t       t         ?

-

+13  SLO*    RLA*    SRE*    RRA*    SHA**   LAX*    DCP*    ISB*    (indir),y

-

+14  NOP*    NOP*    NOP*    NOP*    STY     LDY     NOP*    NOP*    Zeropage,x

-

+15  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage,x

-

+16  ASL     ROL     LSR     ROR     STX  y) LDX  y) DEC     INC     Zeropage,x

-

+17  SLO*    RLA*    SRE*    RRA*    SAX* y) LAX* y) DCP*    ISB*    Zeropage,x

-


-

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

-

+19  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,y

-

+1a  NOP*    NOP*    NOP*    NOP*    TXS     TSX     NOP*    NOP*    Implied

-

+1b  SLO*    RLA*    SRE*    RRA*    SHS**   LAS**   DCP*    ISB*    Absolute,y

-

+1c  NOP*    NOP*    NOP*    NOP*    SHY**   LDY     NOP*    NOP*    Absolute,x

-

+1d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,x

-

+1e  ASL     ROL     LSR     ROR     SHX**y) LDX  y) DEC     INC     Absolute,x

-

+1f  SLO*    RLA*    SRE*    RRA*    SHA**y) LAX* y) DCP*    ISB*    Absolute,x

-


-

       ROR intruction is available on MC650x microprocessors after

-

       June, 1976.

-


-

       Legend:

-


-

       t       Jams the machine

-

       *t      Jams very rarely

-

       *       Undocumented command

-

       **      Unusual operation

-

       y)      indexed using Y instead of X

-

       ()      indirect instead of absolute

-


-

Note that the NOP instructions do have other addressing modes than the

-

implied addressing. The NOP instruction is just like any other load

-

instruction, except it does not store the result anywhere nor affects the

-

flags.

-


-

6502 Registers

-


-

The NMOS 65xx processors are not ruined with too many registers. In addition

-

to that, the registers are mostly 8-bit. Here is a brief description of each

-

register:

-


-

    PC Program Counter

-

         This register points the address from which the next instruction

-

         byte (opcode or parameter) will be fetched. Unlike other

-

         registers, this one is 16 bits in length. The low and high 8-bit

-

         halves of the register are called PCL and PCH, respectively. The

-

         Program Counter may be read by pushing its value on the stack.

-

         This can be done either by jumping to a subroutine or by causing

-

         an interrupt.

-

    S Stack pointer

-

         The NMOS 65xx processors have 256 bytes of stack memory, ranging

-

         from $0100 to $01FF. The S register is a 8-bit offset to the stack

-

         page. In other words, whenever anything is being pushed on the

-

         stack, it will be stored to the address $0100+S.

-


-

         The Stack pointer can be read and written by transfering its value

-

         to or from the index register X (see below) with the TSX and TXS

-

         instructions.

-

    P Processor status

-

         This 8-bit register stores the state of the processor. The bits in

-

         this register are called flags. Most of the flags have something

-

         to do with arithmetic operations.

-


-

         The P register can be read by pushing it on the stack (with PHP or

-

         by causing an interrupt). If you only need to read one flag, you

-

         can use the branch instructions. Setting the flags is possible by

-

         pulling the P register from stack or by using the flag set or

-

         clear instructions.

-


-

         Following is a list of the flags, starting from the 8th bit of the

-

         P register (bit 7, value $80):

-

              N Negative flag

-

                   This flag will be set after any arithmetic operations

-

                   (when any of the registers A, X or Y is being loaded

-

                   with a value). Generally, the N flag will be copied from

-

                   the topmost bit of the register being loaded.

-


-

                   Note that TXS (Transfer X to S) is not an arithmetic

-

                   operation. Also note that the BIT instruction affects

-

                   the Negative flag just like arithmetic operations.

-

                   Finally, the Negative flag behaves differently in

-

                   Decimal operations (see description below).

-

              V oVerflow flag

-

                   Like the Negative flag, this flag is intended to be used

-

                   with 8-bit signed integer numbers. The flag will be

-

                   affected by addition and subtraction, the instructions

-

                   PLP, CLV and BIT, and the hardware signal -SO. Note that

-

                   there is no SEV instruction, even though the MOS

-

                   engineers loved to use East European abbreviations, like

-

                   DDR (Deutsche Demokratische Republik vs. Data Direction

-

                   Register). (The Russian abbreviation for their former

-

                   trade association COMECON is SEV.) The -SO (Set

-

                   Overflow) signal is available on some processors, at

-

                   least the 6502, to set the V flag. This enables response

-

                   to an I/O activity in equal or less than three clock

-

                   cycles when using a BVC instruction branching to itself

-

                   ($50 $FE).

-


-

                   The CLV instruction clears the V flag, and the PLP and

-

                   BIT instructions copy the flag value from the bit 6 of

-

                   the topmost stack entry or from memory.

-


-

                   After a binary addition or subtraction, the V flag will

-

                   be set on a sign overflow, cleared otherwise. What is a

-

                   sign overflow? For instance, if you are trying to add

-

                   123 and 45 together, the result (168) does not fit in a

-

                   8-bit signed integer (upper limit 127 and lower limit

-

                   -128). Similarly, adding -123 to -45 causes the

-

                   overflow, just like subtracting -45 from 123 or 123 from

-

                   -45 would do.

-


-

                   Like the N flag, the V flag will not be set as expected

-

                   in the Decimal mode. Later in this document is a precise

-

                   operation description.

-


-

                   A common misbelief is that the V flag could only be set

-

                   by arithmetic operations, not cleared.

-

              1 unused flag

-

                   To the current knowledge, this flag is always 1.

-

              B Break flag

-

                   This flag is used to distinguish software (BRK)

-

                   interrupts from hardware interrupts (IRQ or NMI). The B

-

                   flag is always set except when the P register is being

-

                   pushed on stack when jumping to an interrupt routine to

-

                   process only a hardware interrupt.

-


-

                   The official NMOS 65xx documentation claims that the BRK

-

                   instruction could only cause a jump to the IRQ vector

-

                   ($FFFE). However, if an NMI interrupt occurs while

-

                   executing a BRK instruction, the processor will jump to

-

                   the NMI vector ($FFFA), and the P register will be

-

                   pushed on the stack with the B flag set.

-

              D Decimal mode flag

-

                   This flag is used to select the (Binary Coded) Decimal

-

                   mode for addition and subtraction. In most applications,

-

                   the flag is zero.

-


-

                   The Decimal mode has many oddities, and it operates

-

                   differently on CMOS processors. See the description of

-

                   the ADC, SBC and ARR instructions below.

-

              I Interrupt disable flag

-

                   This flag can be used to prevent the processor from

-

                   jumping to the IRQ handler vector ($FFFE) whenever the

-

                   hardware line -IRQ is active. The flag will be

-

                   automatically set after taking an interrupt, so that the

-

                   processor would not keep jumping to the interrupt

-

                   routine if the -IRQ signal remains low for several clock

-

                   cycles.

-

              Z Zero flag

-

                   The Zero flag will be affected in the same cases than

-

                   the Negative flag. Generally, it will be set if an

-

                   arithmetic register is being loaded with the value zero,

-

                   and cleared otherwise. The flag will behave differently

-

                   in Decimal operations.

-

              C Carry flag

-

                   This flag is used in additions, subtractions,

-

                   comparisons and bit rotations. In additions and

-

                   subtractions, it acts as a 9th bit and lets you to chain

-

                   operations to calculate with bigger than 8-bit numbers.

-

                   When subtracting, the Carry flag is the negative of

-

                   Borrow: if an overflow occurs, the flag will be clear,

-

                   otherwise set. Comparisons are a special case of

-

                   subtraction: they assume Carry flag set and Decimal flag

-

                   clear, and do not store the result of the subtraction

-

                   anywhere.

-


-

                   There are four kinds of bit rotations. All of them store

-

                   the bit that is being rotated off to the Carry flag. The

-

                   left shifting instructions are ROL and ASL. ROL copies

-

                   the initial Carry flag to the lowmost bit of the byte;

-

                   ASL always clears it. Similarly, the ROR and LSR

-

                   instructions shift to the right.

-

    A Accumulator

-

         The accumulator is the main register for arithmetic and logic

-

         operations. Unlike the index registers X and Y, it has a direct

-

         connection to the Arithmetic and Logic Unit (ALU). This is why

-

         many operations are only available for the accumulator, not the

-

         index registers.

-

    X Index register X

-

         This is the main register for addressing data with indices. It has

-

         a special addressing mode, indexed indirect, which lets you to

-

         have a vector table on the zero page.

-

    Y Index register Y

-

         The Y register has the least operations available. On the other

-

         hand, only it has the indirect indexed addressing mode that

-

         enables access to any memory place without having to use

-

         self-modifying code.

-


-

6510/8502 Undocumented Commands

-


-

-- A brief explanation about what may happen while using don't care states.

-


-

       ANE $8B         A = (A | #$EE) & X & #byte

-

                       same as

-

                       A = ((A & #$11 & X) | ( #$EE & X)) & #byte

-


-

                       In real 6510/8502 the internal parameter #$11

-

                       may occasionally be #$10, #$01 or even #$00.

-

                       This occurs when the video chip starts DMA

-

                       between the opcode fetch and the parameter fetch

-

                       of the instruction.  The value probably depends

-

                       on the data that was left on the bus by the VIC-II.

-


-

       LXA $AB         C=Lehti:   A = X = ANE

-

                       Alternate: A = X = (A & #byte)

-


-

                       TXA and TAX have to be responsible for these.

-


-

       SHA $93,$9F     Store (A & X & (ADDR_HI + 1))

-

       SHX $9E         Store (X & (ADDR_HI + 1))

-

       SHY $9C         Store (Y & (ADDR_HI + 1))

-

       SHS $9B         SHA and TXS, where X is replaced by (A & X).

-


-

                       Note: The value to be stored is copied also

-

                       to ADDR_HI if page boundary is crossed.

-


-

       SBX $CB         Carry and Decimal flags are ignored but the

-

                       Carry flag will be set in substraction. This

-

                       is due to the CMP command, which is executed

-

                       instead of the real SBC.

-


-

       ARR $6B         This instruction first performs an AND

-

                       between the accumulator and the immediate

-

                       parameter, then it shifts the accumulator to

-

                       the right. However, this is not the whole

-

                       truth. See the description below.

-


-

Many undocumented commands do not use AND between registers, the CPU

-

just throws the bytes to a bus simultaneously and lets the

-

open-collector drivers perform the AND. I.e. the command called 'SAX',

-

which is in the STORE section (opcodes $A0...$BF), stores the result

-

of (A & X) by this way.

-


-

More fortunate is its opposite, 'LAX' which just loads a byte

-

simultaneously into both A and X.

-


-

       $6B  ARR

-


-

This instruction seems to be a harmless combination of AND and ROR at

-

first sight, but it turns out that it affects the V flag and also has

-

a special kind of decimal mode. This is because the instruction has

-

inherited some properties of the ADC instruction ($69) in addition to

-

the ROR ($6A).

-


-

In Binary mode (D flag clear), the instruction effectively does an AND

-

between the accumulator and the immediate parameter, and then shifts

-

the accumulator to the right, copying the C flag to the 8th bit. It

-

sets the Negative and Zero flags just like the ROR would. The ADC code

-

shows up in the Carry and oVerflow flags. The C flag will be copied

-

from the bit 6 of the result (which doesn't seem too logical), and the

-

V flag is the result of an Exclusive OR operation between the bit 6

-

and the bit 5 of the result.  This makes sense, since the V flag will

-

be normally set by an Exclusive OR, too.

-


-

In Decimal mode (D flag set), the ARR instruction first performs the

-

AND and ROR, just like in Binary mode. The N flag will be copied from

-

the initial C flag, and the Z flag will be set according to the ROR

-

result, as expected. The V flag will be set if the bit 6 of the

-

accumulator changed its state between the AND and the ROR, cleared

-

otherwise.

-


-

Now comes the funny part. If the low nybble of the AND result,

-

incremented by its lowmost bit, is greater than 5, the low nybble in

-

the ROR result will be incremented by 6. The low nybble may overflow

-

as a consequence of this BCD fixup, but the high nybble won't be

-

adjusted. The high nybble will be BCD fixed in a similar way. If the

-

high nybble of the AND result, incremented by its lowmost bit, is

-

greater than 5, the high nybble in the ROR result will be incremented

-

by 6, and the Carry flag will be set. Otherwise the C flag will be

-

cleared.

-


-

To help you understand this description, here is a C routine that

-

illustrates the ARR operation in Decimal mode:

-


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          t,  /* temporary value */

-

          s;  /* value to be ARRed with Accumulator */

-


-

       t = A & s;                      /* Perform the AND. */

-


-

       AH = t >> 4;                    /* Separate the high */

-

       AL = t & 15;                    /* and low nybbles. */

-


-

       N = C;                          /* Set the N and */

-

       Z = !(A = (t >> 1) | (C << 7)); /* Z flags traditionally */

-

       V = (t ^ A) & 64;               /* and V flag in a weird way. */

-


-

       if (AL + (AL & 1) > 5)          /* BCD "fixup" for low nybble. */

-

         A = (A & 0xF0) | ((A + 6) & 0xF);

-


-

       if (C = AH + (AH & 1) > 5)      /* Set the Carry flag. */

-

         A = (A + 0x60) & 0xFF;        /* BCD "fixup" for high nybble. */

-


-

       $CB  SBX   X <- (A & X) - Immediate

-


-

The 'SBX' ($CB) may seem to be very complex operation, even though it

-

is a combination of the subtraction of accumulator and parameter, as

-

in the 'CMP' instruction, and the command 'DEX'. As a result, both A

-

and X are connected to ALU but only the subtraction takes place. Since

-

the comparison logic was used, the result of subtraction should be

-

normally ignored, but the 'DEX' now happily stores to X the value of

-

(A & X) - Immediate.  That is why this instruction does not have any

-

decimal mode, and it does not affect the V flag. Also Carry flag will

-

be ignored in the subtraction but set according to the result.

-


-

Proof:

-


-

begin 644 vsbx

-

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```*D`H#V1*Z`_D2N@09$KJ0>%

-

M^QBE^VEZJ+$KH#F1*ZD`2"BI`*(`RP`(:-B@.5$K*4#P`E@`H#VQ*SAI`)$K

-

JD-Z@/[$K:0"1*Y#4J2X@TO\XH$&Q*VD`D2N0Q,;[$+188/_^]_:_OK>V

-

`

-

end

-


-

and

-


-

begin 644 sbx

-

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI`*!-D2N@3Y$KH%&1*ZD#

-

MA?L8I?M*2)`#J1@LJ3B@29$K:$J0`ZGX+*G8R)$K&/BXJ?2B8\L)AOP(:(7]

-

MV#B@3;$KH$\Q*Z!1\2L(1?SP`0!H1?TIM]#XH$VQ*SAI`)$KD,N@3[$K:0"1

-

9*Y#!J2X@TO\XH%&Q*VD`D2N0L<;[$))88-#X

-

`

-

end

-


-

These test programs show if your machine is compatible with ours

-

regarding the opcode $CB. The first test, vsbx, proves that SBX does

-

not affect the V flag. The latter one, sbx, proves the rest of our

-

theory. The vsbx test tests 33554432 SBX combinations (16777216

-

different A, X and Immediate combinations, and two different V flag

-

states), and the sbx test doubles that amount (16777216*4 D and C flag

-

combinations). Both tests have run successfully on a C64 and a Vic20.

-

They ought to run on C16, +4 and the PET series as well. The tests

-

stop with BRK, if the opcode $CB does not work as expected. Successful

-

operation ends in RTS. As the tests are very slow, they print dots on

-

the screen while running so that you know that the machine has not

-

jammed. On computers running at 1 MHz, the first test prints

-

approximately one dot every four seconds and a total of 2048 dots,

-

whereas the second one prints half that amount, one dot every seven

-

seconds.

-


-

If the tests fail on your machine, please let us know your processor's

-

part number and revision. If possible, save the executable (after it

-

has stopped with BRK) under another name and send it to us so that we

-

know at which stage the program stopped.

-


-

The following program is a Commodore 64 executable that Marko M"akel"a

-

developed when trying to find out how the V flag is affected by SBX.

-

(It was believed that the SBX affects the flag in a weird way, and

-

this program shows how SBX sets the flag differently from SBC.)  You

-

may find the subroutine at $C150 useful when researching other

-

undocumented instructions' flags. Run the program in a machine

-

language monitor, as it makes use of the BRK instruction. The result

-

tables will be written on pages $C2 and $C3.

-


-

begin 644 sbx-c100

-

M`,%XH`",#L&,$,&,$L&XJ8*B@LL7AOL(:(7\N#BM#L$M$,'M$L$(Q?OP`B@`

-

M:$7\\`,@4,'N#L'0U.X0P=#/SB#0[A+!T,<``````````````)BJ\!>M#L$M

-

L$,'=_\'0":T2P=W_PM`!8,K0Z:T.P2T0P9D`PID`!*T2P9D`PYD`!

-


-

Other undocumented instructions usually cause two preceding opcodes

-

being executed. However 'NOP' seems to completely disappear from 'SBC'

-

code $EB.

-


-

The most difficult to comprehend are the rest of the instructions

-

located on the '$0B' line.

-


-

All the instructions located at the positive (left) side of this line

-

should rotate either memory or the accumulator, but the addressing

-

mode turns out to be immediate! No problem. Just read the operand, let

-

it be ANDed with the accumulator and finally use accumulator

-

addressing mode for the instructions above them.

-


-

RELIGION_MODE_ON

-

/* This part of the document is not accurate.  You can

-

  read it as a fairy tale, but do not count on it when

-

  performing your own measurements. */

-


-

The rest two instructions on the same line, called 'ANE' and 'LXA'

-

($8B and $AB respectively) often give quite unpredictable results.

-

However, the most usual operation is to store ((A | #$ee) & X & #$nn)

-

to accumulator. Note that this does not work reliably in a real 64!

-

In the Commodore 128 the opcode $8B uses values 8C, CC, EE, and

-

occasionally 0C and 8E for the OR instead of EE,EF,FE and FF used in

-

the C64. With a C128 running at 2 MHz #$EE is always used.  Opcode $AB

-

does not cause this OR taking place on 8502 while 6510 always performs

-

it. Note that this behaviour depends on processor and/or video chip

-

revision.

-


-

Let's take a closer look at $8B (6510).

-


-

       A <- X & D & (A | VAL)

-


-

       where VAL comes from this table:

-


-

      X high   D high  D low   VAL

-

       even     even    ---    $EE (1)

-

       even     odd     ---    $EE

-

       odd      even    ---    $EE

-

       odd      odd      0     $EE

-

       odd      odd     not 0  $FE (2)

-


-

(1) If the bottom 2 bits of A are both 1, then the LSB of the result may

-

   be 0. The values of X and D are different every time I run the test.

-

   This appears to be very rare.

-

(2) VAL is $FE most of the time. Sometimes it is $EE - it seems to be random,

-

   not related to any of the data. This is much more common than (1).

-


-

 In decimal mode, VAL is usually $FE.

-


-

Two different functions have been discovered for LAX, opcode $AB. One

-

is A = X = ANE (see above) and the other, encountered with 6510 and

-

8502, is less complicated A = X = (A & #byte). However, according to

-

what is reported, the version altering only the lowest bits of each

-

nybble seems to be more common.

-


-

What happens, is that $AB loads a value into both A and X, ANDing the

-

low bit of each nybble with the corresponding bit of the old

-

A. However, there are exceptions. Sometimes the low bit is cleared

-

even when A contains a '1', and sometimes other bits are cleared. The

-

exceptions seem random (they change every time I run the test). Oops -

-

that was in decimal mode. Much the same with D=0.

-


-

What causes the randomness?  Probably it is that it is marginal logic

-

levels - when too much wired-anding goes on, some of the signals get

-

very close to the threshold. Perhaps we're seeing some of them step

-

over it. The low bit of each nybble is special, since it has to cope

-

with carry differently (remember decimal mode). We never see a '0'

-

turn into a '1'.

-


-

Since these instructions are unpredictable, they should not be used.

-


-

There is still very strange instruction left, the one named SHA/X/Y,

-

which is the only one with only indexed addressing modes. Actually,

-

the commands 'SHA', 'SHX' and 'SHY' are generated by the indexing

-

algorithm.

-


-

While using indexed addressing, effective address for page boundary

-

crossing is calculated as soon as possible so it does not slow down

-

operation. As a result, in the case of SHA/X/Y, the address and data

-

are processed at the same time making AND between them to take place.

-

Thus, the value to be stored by SAX, for example, is in fact (A & X &

-

(ADDR_HI + 1)).  On page boundary crossing the same value is copied

-

also to high byte of the effective address.

-


-

RELIGION_MODE_OFF

-


-


-

Register selection for load and store

-


-

  bit1 bit0     A  X  Y

-

   0    0             x

-

   0    1          x

-

   1    0       x

-

   1    1       x  x

-


-

So, A and X are selected by bits 1 and 0 respectively, while

-

~(bit1|bit0) enables Y.

-


-

Indexing is determined by bit4, even in relative addressing mode,

-

which is one kind of indexing.

-


-

Lines containing opcodes xxx000x1 (01 and 03) are treated as absolute

-

after the effective address has been loaded into CPU.

-


-

Zeropage,y and Absolute,y (codes 10x1 x11x) are distinquished by bit5.

-


-


-

Decimal mode in NMOS 6500 series

-


-

 Most sources claim that the NMOS 6500 series sets the N, V and Z

-

flags unpredictably when performing addition or subtraction in decimal

-

mode. Of course, this is not true. While testing how the flags are

-

set, I also wanted to see what happens if you use illegal BCD values.

-


-

 ADC works in Decimal mode in a quite complicated way. It is amazing

-

how it can do that all in a single cycle. Here's a C code version of

-

the instruction:

-


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          s;  /* value to be added to Accumulator */

-


-

       AL = (A & 15) + (s & 15) + C;         /* Calculate the lower nybble. */

-


-

       AH = (A >> 4) + (s >> 4) + (AL > 15); /* Calculate the upper nybble. */

-


-

       if (AL > 9) AL += 6;                  /* BCD fixup for lower nybble. */

-


-

       Z = ((A + s + C) & 255 != 0);         /* Zero flag is set just

-

                                                like in Binary mode. */

-


-

       /* Negative and Overflow flags are set with the same logic than in

-

          Binary mode, but after fixing the lower nybble. */

-


-

       N = (AH & 8 != 0);

-

       V = ((AH << 4) ^ A) & 128 && !((A ^ s) & 128);

-


-

       if (AH > 9) AH += 6;                  /* BCD fixup for upper nybble. */

-


-

       /* Carry is the only flag set after fixing the result. */

-


-

       C = (AH > 15);

-

       A = ((AH << 4) | (AL & 15)) & 255;

-


-

 The C flag is set as the quiche eaters expect, but the N and V flags

-

are set after fixing the lower nybble but before fixing the upper one.

-

They use the same logic than binary mode ADC. The Z flag is set before

-

any BCD fixup, so the D flag does not have any influence on it.

-


-

Proof: The following test program tests all 131072 ADC combinations in

-

      Decimal mode, and aborts with BRK if anything breaks this theory.

-

      If everything goes well, it ends in RTS.

-


-

begin 600 dadc

-

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH(V1

-

M*Q@(I?PI#X7]I?LI#V7]R0J0 FD%J"D/A?VE^RGP9?PI\ C $) ":0^JL @H

-

ML ?)H) &""@X:5\X!?V%_0AH*3W@ ! ""8"HBD7[$ JE^T7\, 28"4"H**7[

-

M9?S0!)@) J@8N/BE^V7\V A%_= G:(3]1?W0(.;[T(?F_-"#:$D8\ )88*D=

-

0&&4KA?NI &4LA?RI.&S[  A%

-


-

end

-


-

 All programs in this chapter have been successfully tested on a Vic20

-

and a Commodore 64 and a Commodore 128D in C64 mode. They should run on

-

C16, +4 and on the PET series as well. If not, please report the problem

-

to Marko M"akel"a. Each test in this chapter should run in less than a

-

minute at 1 MHz.

-


-

SBC is much easier. Just like CMP, its flags are not affected by

-

the D flag.

-


-

Proof:

-


-

begin 600 dsbc-cmp-flags

-

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'B@ (3[A/RB XH8:66HL2N@

-

M09$KH$R1*XII::BQ*Z!%D2N@4)$K^#BXI?OE_-@(:(7].+BE^^7\"&A%_? !

-

5 .;[T./F_-#?RA"_8!@X&#CEY<7%

-


-

end

-


-

 The only difference in SBC's operation in decimal mode from binary mode

-

is the result-fixup:

-


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          s;  /* value to be added to Accumulator */

-


-

       AL = (A & 15) - (s & 15) - !C;        /* Calculate the lower nybble. */

-


-

       if (AL & 16) AL -= 6;                 /* BCD fixup for lower nybble. */

-


-

       AH = (A >> 4) - (s >> 4) - (AL & 16); /* Calculate the upper nybble. */

-


-

       if (AH & 16) AH -= 6;                 /* BCD fixup for upper nybble. */

-


-

       /* The flags are set just like in Binary mode. */

-


-

       C = (A - s - !C) & 256 != 0;

-

       Z = (A - s - !C) & 255 != 0;

-

       V = ((A - s - !C) ^ s) & 128 && (A ^ s) & 128;

-

       N = (A - s - !C) & 128 != 0;

-


-

       A = ((AH << 4) | (AL & 15)) & 255;

-


-

 Again Z flag is set before any BCD fixup. The N and V flags are set

-

at any time before fixing the high nybble. The C flag may be set in any

-

phase.

-


-

 Decimal subtraction is easier than decimal addition, as you have to

-

make the BCD fixup only when a nybble overflows. In decimal addition,

-

you had to verify if the nybble was greater than 9. The processor has

-

an internal "half carry" flag for the lower nybble, used to trigger

-

the BCD fixup. When calculating with legal BCD values, the lower nybble

-

cannot overflow again when fixing it.

-

So, the processor does not handle overflows while performing the fixup.

-

Similarly, the BCD fixup occurs in the high nybble only if the value

-

overflows, i.e. when the C flag will be cleared.

-


-

 Because SBC's flags are not affected by the Decimal mode flag, you

-

could guess that CMP uses the SBC logic, only setting the C flag

-

first. But the SBX instruction shows that CMP also temporarily clears

-

the D flag, although it is totally unnecessary.

-


-

 The following program, which tests SBC's result and flags,

-

contains the 6502 version of the pseudo code example above.

-


-

begin 600 dsbc

-

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH':1

-

M*S@(I?PI#X7]I?LI#^7]L /I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL KI7RBP

-

M#ND/.+ )*+ &Z0^P NE?A/T%_87]*+BE^^7\"&BH.+CXI?OE_-@(1?W0FVB$

-

8_47]T)3F^]">YOS0FFA)&- $J3C0B%A@

-


-

end

-


-

 Obviously the undocumented instructions RRA (ROR+ADC) and ISB

-

(INC+SBC) have inherited also the decimal operation from the official

-

instructions ADC and SBC. The program droradc proves this statement

-

for ROR, and the dincsbc test proves this for ISB. Finally,

-

dincsbc-deccmp proves that ISB's and DCP's (DEC+CMP) flags are not

-

affected by the D flag.

-


-

begin 644 droradc

-

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH(V1

-

M*S@(I?PI#X7]I?LI#V7]R0J0`FD%J"D/A?VE^RGP9?PI\`C`$)`":0^JL`@H

-

ML`?)H)`&""@X:5\X!?V%_0AH*3W@`!`""8"HBD7[$`JE^T7\,`28"4"H**7[

-

M9?S0!)@)`J@XN/BE^R;\9_S8"$7]T"=HA/U%_=`@YOO0A>;\T(%H21CP`EA@

-

2J1T892N%^ZD`92R%_*DX;/L`

-

`

-

end

-


-

begin 644 dincsbc

-

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH':1

-

M*S@(I?PI#X7]I?LI#^7]L`/I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL`KI7RBP

-

M#ND/.+`)*+`&Z0^P`NE?A/T%_87]*+BE^^7\"&BH.+CXI?O&_.?\V`A%_="9

-

::(3]1?W0DN;[T)SF_-"8:$D8T`2I.-"&6&#\

-

`

-

end

-


-

begin 644 dincsbc-deccmp

-

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'B@`(3[A/RB`XH8:7>HL2N@

-

M3Y$KH%R1*XII>ZBQ*Z!3D2N@8)$KBFE_J+$KH%61*Z!BD2OX.+BE^^;\Q_S8

-

L"&B%_3BXI?OF_,?\"&A%_?`!`.;[T-_F_-#;RA"M8!@X&#CFYL;&Q\?GYP#8

-

`

-

end

-


-


-

6510 features

-


-

  o  PHP always pushes the Break (B) flag as a `1' to the stack.

-

     Jukka Tapanim"aki claimed in C=lehti issue 3/89, on page 27 that the

-

     processor makes a logical OR between the status register's bit 4

-

     and the bit 8 of the stack pointer register (which is always 1).

-

     He did not give any reasons for this argument, and has refused to clarify

-

     it afterwards. Well, this was not the only error in his article...

-


-

  o  Indirect addressing modes do not handle page boundary crossing at all.

-

     When the parameter's low byte is $FF, the effective address wraps

-

     around and the CPU fetches high byte from $xx00 instead of $xx00+$0100.

-

     E.g. JMP ($01FF) fetches PCL from $01FF and PCH from $0100,

-

     and LDA ($FF),Y fetches the base address from $FF and $00.

-


-

  o  Indexed zero page addressing modes never fix the page address on

-

     crossing the zero page boundary.

-

     E.g. LDX #$01 : LDA ($FF,X) loads the effective address from $00 and $01.

-


-

  o  The processor always fetches the byte following a relative branch

-

     instruction. If the branch is taken, the processor reads then the

-

     opcode from the destination address. If page boundary is crossed, it

-

     first reads a byte from the old page from a location that is bigger

-

     or smaller than the correct address by one page.

-


-

  o  If you cross a page boundary in any other indexed mode,

-

     the processor reads an incorrect location first, a location that is

-

     smaller by one page.

-


-

  o  Read-Modify-Write instructions write unmodified data, then modified

-

     (so INC effectively does LDX loc;STX loc;INX;STX loc)

-


-

  o  -RDY is ignored during writes

-

     (This is why you must wait 3 cycles before doing any DMA --

-

     the maximum number of consecutive writes is 3, which occurs

-

     during interrupts except -RESET.)

-


-

  o  Some undefined opcodes may give really unpredictable results.

-


-

  o  All registers except the Program Counter remain unmodified after -RESET.

-

     (This is why you must preset D and I flags in the RESET handler.)

-


-


-

Different CPU types

-


-

The Rockwell data booklet 29651N52 (technical information about R65C00

-

microprocessors, dated October 1984), lists the following differences between

-

NMOS R6502 microprocessor and CMOS R65C00 family:

-


-


-

    1. Indexed addressing across page boundary.

-

            NMOS: Extra read of invalid address.

-

            CMOS: Extra read of last instruction byte.

-


-


-

    2. Execution of invalid op codes.

-

            NMOS: Some terminate only by reset. Results are undefined.

-

            CMOS: All are NOPs (reserved for future use).

-


-


-

    3. Jump indirect, operand = XXFF.

-

            NMOS: Page address does not increment.

-

            CMOS: Page address increments and adds one additional cycle.

-


-


-

    4. Read/modify/write instructions at effective address.

-

            NMOS: One read and two write cycles.

-

            CMOS: Two read and one write cycle.

-


-


-

    5. Decimal flag.

-

            NMOS: Indeterminate after reset.

-

            CMOS: Initialized to binary mode (D=0) after reset and interrupts.

-


-


-

    6. Flags after decimal operation.

-

            NMOS: Invalid N, V and Z flags.

-

            CMOS: Valid flag adds one additional cycle.

-


-


-

    7. Interrupt after fetch of BRK instruction.

-

            NMOS: Interrupt vector is loaded, BRK vector is ignored.

-

            CMOS: BRK is executed, then interrupt is executed.

-


-


-

6510 Instruction Timing

-


-

 The NMOS 6500 series processors always perform at least two reads

-

for each instruction. In addition to the operation code (opcode), they

-

fetch the next byte. This is quite efficient, as most instructions are

-

two or three bytes long.

-


-

 The processors also use a sort of pipelining. If an instruction does

-

not store data in memory on its last cycle, the processor can fetch

-

the opcode of the next instruction while executing the last cycle. For

-

instance, the instruction EOR #$FF truly takes three cycles. On the

-

first cycle, the opcode $49 will be fetched. During the second cycle

-

the processor decodes the opcode and fetches the parameter #$FF. On

-

the third cycle, the processor will perform the operation and store

-

the result to accumulator, but simultaneously it fetches the opcode

-

for the next instruction. This is why the instruction effectively

-

takes only two cycles.

-


-

 The following tables show what happens on the bus while executing

-

different kinds of instructions.

-


-

 Interrupts

-


-

    NMI and IRQ both take 7 cycles. Their timing diagram is much like

-

    BRK's (see below). IRQ will be executed only when the I flag is

-

    clear. IRQ and BRK both set the I flag, whereas the NMI does not

-

    affect its state.

-


-

    The processor will usually wait for the current instruction to

-

    complete before executing the interrupt sequence. To process the

-

    interrupt before the next instruction, the interrupt must occur

-

    before the last cycle of the current instruction.

-


-

    There is one exception to this rule: the BRK instruction. If a

-

    hardware interrupt (NMI or IRQ) occurs before the fourth (flags

-

    saving) cycle of BRK, the BRK instruction will be skipped, and

-

    the processor will jump to the hardware interrupt vector. This

-

    sequence will always take 7 cycles.

-


-

    You do not completely lose the BRK interrupt, the B flag will be

-

    set in the pushed status register if a BRK instruction gets

-

    interrupted. When BRK and IRQ occur at the same time, this does

-

    not cause any problems, as your program will consider it as a

-

    BRK, and the IRQ would occur again after the processor returned

-

    from your BRK routine, unless you cleared the interrupt source in

-

    your BRK handler. But the simultaneous occurrence of NMI and BRK

-

    is far more fatal. If you do not check the B flag in the NMI

-

    routine and subtract two from the return address when needed, the

-

    BRK instruction will be skipped.

-


-

    If the NMI and IRQ interrupts overlap each other (one interrupt

-

    occurs before fetching the interrupt vector for the other

-

    interrupt), the processor will most probably jump to the NMI

-

    vector in every case, and then jump to the IRQ vector after

-

    processing the first instruction of the NMI handler. This has not

-

    been measured yet, but the IRQ is very similar to BRK, and many

-

    sources state that the NMI has higher priority than IRQ. However,

-

    it might be that the processor takes the interrupt that comes

-

    later, i.e. you could lose an NMI interrupt if an IRQ occurred in

-

    four cycles after it.

-


-

    After finishing the interrupt sequence, the processor will start

-

    to execute the first instruction of the interrupt routine. This

-

    proves that the processor uses a sort of pipelining: it finishes

-

    the current instruction (or interrupt sequence) while reading the

-

    opcode of the next instruction.

-


-

    RESET does not push program counter on stack, and it lasts

-

    probably 6 cycles after deactivating the signal. Like NMI, RESET

-

    preserves all registers except PC.

-


-

 Instructions accessing the stack

-


-

    BRK

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away),

-

                      increment PC

-

       3  $0100,S  W  push PCH on stack (with B flag set), decrement S

-

       4  $0100,S  W  push PCL on stack, decrement S

-

       5  $0100,S  W  push P on stack, decrement S

-

       6   $FFFE   R  fetch PCL

-

       7   $FFFF   R  fetch PCH

-


-

    RTI

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull P from stack, increment S

-

       5  $0100,S  R  pull PCL from stack, increment S

-

       6  $0100,S  R  pull PCH from stack

-


-

    RTS

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull PCL from stack, increment S

-

       5  $0100,S  R  pull PCH from stack

-

       6    PC     R  increment PC

-


-

    PHA, PHP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  W  push register on stack, decrement S

-


-

    PLA, PLP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull register from stack

-


-

    JSR

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

       3  $0100,S  R  internal operation (predecrement S?)

-

       4  $0100,S  W  push PCH on stack, decrement S

-

       5  $0100,S  W  push PCL on stack, decrement S

-

       6    PC     R  copy low address byte to PCL, fetch high address

-

                      byte to PCH

-


-

 Accumulator or implied addressing

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-


-

 Immediate addressing

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch value, increment PC

-


-

 Absolute addressing

-


-

    JMP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

       3    PC     R  copy low address byte to PCL, fetch high address

-

                      byte to PCH

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, NOP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-

       5  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       6  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  W  write register to effective address

-


-

 Zero page addressing

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, NOP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-

       4  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       5  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  W  write register to effective address

-


-

 Zero page indexed addressing

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, NOP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

       3   address   R  read from address, add index register to it

-

       4  address+I* R  read from effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address is always zero,

-

               i.e. page boundary crossings are not handled.

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

       3   address   R  read from address, add index register X to it

-

       4  address+X* R  read from effective address

-

       5  address+X* W  write the value back to effective address,

-

                        and do the operation on it

-

       6  address+X* W  write the new value to effective address

-


-

      Note: * The high byte of the effective address is always zero,

-

              i.e. page boundary crossings are not handled.

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

       3   address   R  read from address, add index register to it

-

       4  address+I* W  write to effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address is always zero,

-

               i.e. page boundary crossings are not handled.

-


-

 Absolute indexed addressing

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, LAE, SHS, NOP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

       5+ address+I  R  re-read from effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

             + This cycle will be executed only if the effective address

-

               was invalid during cycle #4, i.e. page boundary was crossed.

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #   address  R/W description

-

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

-

       1    PC       R  fetch opcode, increment PC

-

       2    PC       R  fetch low byte of address, increment PC

-

       3    PC       R  fetch high byte of address,

-

                        add index register X to low address byte,

-

                        increment PC

-

       4  address+X* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+X  R  re-read from effective address

-

       6  address+X  W  write the value back to effective address,

-

                        and do the operation on it

-

       7  address+X  W  write the new value to effective address

-


-

      Notes: * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

    Write instructions (STA, STX, STY, SHA, SHX, SHY)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+I  W  write to effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100. Because

-

               the processor cannot undo a write to an invalid

-

               address, it always reads from the address first.

-


-

 Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch operand, increment PC

-

       3     PC      R  Fetch opcode of next instruction,

-

                        If branch is taken, add operand to PCL.

-

                        Otherwise increment PC.

-

       4+    PC*     R  Fetch opcode of next instruction.

-

                        Fix PCH. If it did not change, increment PC.

-

       5!    PC      R  Fetch opcode of next instruction,

-

                        increment PC.

-


-

      Notes: The opcode fetch of the next instruction is included to

-

             this diagram for illustration purposes. When determining

-

             real execution times, remember to subtract the last

-

             cycle.

-


-

             * The high byte of Program Counter (PCH) may be invalid

-

               at this time, i.e. it may be smaller or bigger by $100.

-


-

             + If branch is taken, this cycle will be executed.

-


-

             ! If branch occurs to different page, this cycle will be

-

               executed.

-


-

 Indexed indirect addressing

-


-

    Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  read from the address, add X to it

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-


-

      Note: The effective address is always fetched from zero page,

-

            i.e. the zero page boundary crossing is not handled.

-


-

    Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  read from the address, add X to it

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-

       7    address    W  write the value back to effective address,

-

                          and do the operation on it

-

       8    address    W  write the new value to effective address

-


-

      Note: The effective address is always fetched from zero page,

-

            i.e. the zero page boundary crossing is not handled.

-


-

    Write instructions (STA, SAX)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  read from the address, add X to it

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    W  write to effective address

-


-

      Note: The effective address is always fetched from zero page,

-

            i.e. the zero page boundary crossing is not handled.

-


-

 Indirect indexed addressing

-


-

    Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6+  address+Y   R  read from effective address

-


-

      Notes: The effective address is always fetched from zero page,

-

             i.e. the zero page boundary crossing is not handled.

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

             + This cycle will be executed only if the effective address

-

               was invalid during cycle #5, i.e. page boundary was crossed.

-


-

    Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   R  read from effective address

-

       7   address+Y   W  write the value back to effective address,

-

                          and do the operation on it

-

       8   address+Y   W  write the new value to effective address

-


-

      Notes: The effective address is always fetched from zero page,

-

             i.e. the zero page boundary crossing is not handled.

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

    Write instructions (STA, SHA)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   W  write to effective address

-


-

      Notes: The effective address is always fetched from zero page,

-

             i.e. the zero page boundary crossing is not handled.

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

 Absolute indirect addressing (JMP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch pointer address low, increment PC

-

       3     PC      R  fetch pointer address high, increment PC

-

       4   pointer   R  fetch low address to latch

-

       5  pointer+1* R  fetch PCH, copy latch to PCL

-


-

      Note: * The PCH will always be fetched from the same page

-

              than PCL, i.e. page boundary crossing is not handled.

-


-

               How Real Programmers Acknowledge Interrupts

-


-

 With RMW instructions:

-


-

       ; beginning of combined raster/timer interrupt routine

-

       LSR $D019       ; clear VIC interrupts, read raster interrupt flag to C

-

       BCS raster      ; jump if VIC caused an interrupt

-

       ...             ; timer interrupt routine

-


-

       Operational diagram of LSR $D019:

-


-

         #  data  address  R/W

-

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

-

         1   4E     PC      R   fetch opcode

-

         2   19    PC+1     R   fetch address low

-

         3   D0    PC+2     R   fetch address high

-

         4   xx    $D019    R   read memory

-

         5   xx    $D019    W   write the value back, rotate right

-

         6  xx/2   $D019    W   write the new value back

-


-

       The 5th cycle acknowledges the interrupt by writing the same

-

       value back. If only raster interrupts are used, the 6th cycle

-

       has no effect on the VIC. (It might acknowledge also some

-

       other interrupts.)

-


-

 With indexed addressing:

-


-

       ; acknowledge interrupts to both CIAs

-

       LDX #$10

-

       LDA $DCFD,X

-


-

       Operational diagram of LDA $DCFD,X:

-


-

         #  data  address  R/W  description

-

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

-

         1   BD     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

         3   DC    PC+2     R   fetch address high, add X to address low

-

         4   xx    $DC0D    R   read from address, fix high byte of address

-

         5   yy    $DD0D    R   read from right address

-


-

       ; acknowledge interrupts to CIA 2

-

       LDX #$10

-

       STA $DDFD,X

-


-

       Operational diagram of STA $DDFD,X:

-


-

         #  data  address  R/W  description

-

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

-

         1   9D     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

         3   DC    PC+2     R   fetch address high, add X to address low

-

         4   xx    $DD0D    R   read from address, fix high byte of address

-

         5   ac    $DE0D    W   write to right address

-


-

 With branch instructions:

-


-

       ; acknowledge interrupts to CIA 2

-

               LDA #$00  ; clear N flag

-

               JMP $DD0A

-

       DD0A    BPL $DC9D ; branch

-

       DC9D    BRK       ; return

-


-

       You need the following preparations to initialize the CIA registers:

-


-

               LDA #$91  ; argument of BPL

-

               STA $DD0B

-

               LDA #$10  ; BPL

-

               STA $DD0A

-

               STA $DD08 ; load the ToD values from the latches

-

               LDA $DD0B ; freeze the ToD display

-

               LDA #$7F

-

               STA $DC0D ; assure that $DC0D is $00

-


-

       Operational diagram of BPL $DC9D:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DD0A    R   fetch opcode

-

         2   91    $DD0B    R   fetch argument

-

         3   xx    $DD0C    R   fetch opcode, add argument to PCL

-

         4   yy    $DD9D    R   fetch opcode, fix PCH

-

       ( 5   00    $DC9D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 1

-

               LSR       ; clear N flag

-

               JMP $DCFA

-

       DCFA    BPL $DD0D

-

       DD0D    BRK

-


-

       ; Again you need to set the ToD registers of CIA 1 and the

-

       ; Interrupt Control Register of CIA 2 first.

-


-

       Operational diagram of BPL $DD0D:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DCFA    R   fetch opcode

-

         2   11    $DCFB    R   fetch argument

-

         3   xx    $DCFC    R   fetch opcode, add argument to PCL

-

         4   yy    $DC0D    R   fetch opcode, fix PCH

-

       ( 5   00    $DD0D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 2 automagically

-

               ; preparations

-

               LDA #$7F

-

               STA $DD0D       ; disable all interrupt sources of CIA2

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$FD

-

               STA $DD0C       ; parameter of BPL

-

               LDA #$10

-

               STA $DD0B       ; BPL

-

               LDA #$40

-

               STA $DD0A       ; RTI/parameter of LSR

-

               LDA #$46

-

               STA $DD09       ; LSR

-

               STA $DD08       ; load the ToD values from the latches

-

               LDA $DD0B       ; freeze the ToD display

-

               LDA #$09

-

               STA $0318

-

               LDA #$DD

-

               STA $0319       ; change NMI vector to $DD09

-

               LDA #$FF        ; Try changing this instruction's operand

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

               STA $DD04       ; set interrupt frequency to 1/65536 cycles

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

               LDA #$00        ; To see that the interrupts really occur,

-

               STA $D011       ; use something like this and see how

-

       LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

-

               BNE LOOP        ; #$FF to #$0F changes the image.

-


-

       When an NMI occurs, the processor jumps to Kernal code, which jumps to

-

       ($0318), which points to the following routine:

-


-

       DD09    LSR $40         ; clear N flag

-

               BPL $DD0A       ; Note: $DD0A contains RTI.

-


-

       Operational diagram of BPL $DD0A:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DD0B    R   fetch opcode

-

         2   11    $DD0C    R   fetch argument

-

         3   xx    $DD0D    R   fetch opcode, add argument to PCL

-

         4   40    $DD0A    R   fetch opcode, (fix PCH)

-


-

 With RTI:

-


-

       ; the fastest possible interrupt handler in the 6500 family

-

               ; preparations

-

               SEI

-

               LDA $01         ; disable ROM and enable I/O

-

               AND #$FD

-

               ORA #$05

-

               STA $01

-

               LDA #$7F

-

               STA $DD0D       ; disable CIA 2's all interrupt sources

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$40

-

               STA $DD0C       ; store RTI to $DD0C

-

               LDA #$0C

-

               STA $FFFA

-

               LDA #$DD

-

               STA $FFFB       ; change NMI vector to $DD0C

-

               LDA #$FF        ; Try changing this instruction's operand

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

               STA $DD04       ; set interrupt frequency to 1/65536 cycles

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

               LDA #$00        ; To see that the interrupts really occur,

-

               STA $D011       ; use something like this and see how

-

       LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

-

               BNE LOOP        ; #$FF to #$0F changes the image.

-


-

       When an NMI occurs, the processor jumps to Kernal code, which

-

       jumps to ($0318), which points to the following routine:

-


-

       DD0C    RTI

-


-

       How on earth can this clear the interrupts? Remember, the

-

       processor always fetches two successive bytes for each

-

       instruction.

-


-

       A little more practical version of this is redirecting the NMI

-

       (or IRQ) to your own routine, whose last instruction is JMP

-

       $DD0C or JMP $DC0C.  If you want to confuse more, change the 0

-

       in the address to a hexadecimal digit different from the one

-

       you used when writing the RTI.

-


-

       Or you can combine the latter two methods:

-


-

       DD09    LSR $xx  ; xx is any appropriate BCD value 00-59.

-

               BPL $DCFC

-

       DCFC    RTI

-


-

       This example acknowledges interrupts to both CIAs.

-


-

 If you want to confuse the examiners of your code, you can use any

-

of these techniques. Although these examples use no undefined opcodes,

-

they do not necessarily run correctly on CMOS processors. However, the

-

RTI example should run on 65C02 and 65C816, and the latter branch

-

instruction example might work as well.

-


-

 The RMW instruction method has been used in some demos, others were

-

developed by Marko M"akel"a. His favourite is the automagical RTI

-

method, although it does not have any practical applications, except

-

for some time dependent data decryption routines for very complicated

-

copy protections.

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured multi-format Help generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

CPU - 6502

+ +
+ +

+

#

+

# $Id: 6502_cpu.txt,v 1.1.1.1 2004/08/29 01:29:35 bryan Exp $

+

#

+

# This file is part of Commodore 64 emulator

+

#      and Program Development System.

+

#

+

# See README for copyright notice

+

#

+

# This file contains documentation for 6502/6510/8500/8502 instruction set.

+

#

+

#

+

# Written by

+

#   John West       (john@ucc.gu.uwa.edu.au)

+

#   Marko MЉkelЉ    (msmakela@kruuna.helsinki.fi)

+

#

+

#

+

# $Log: 6502_cpu.txt,v $

+

# Revision 1.1.1.1  2004/08/29 01:29:35  bryan

+

# no message

+

#

+

# Revision 1.1  2002/05/21 00:42:27  xodnizel

+

# updates

+

#

+

# Revision 1.8  1994/06/03  19:50:04  jopi

+

# Patchlevel 2

+

#

+

# Revision 1.7  1994/04/15  13:07:04  jopi

+

# 65xx Register descriptions added

+

#

+

# Revision 1.6  1994/02/18  16:09:36  jopi

+

#

+

# Revision 1.5  1994/01/26  16:08:37  jopi

+

# X64 version 0.2 PL 1

+

#

+

# Revision 1.4  1993/11/10  01:55:34  jopi

+

#

+

# Revision 1.3  93/06/21  13:37:18  jopi

+

#  X64 version 0.2 PL 0

+

#

+

# Revision 1.2  93/06/21  13:07:15  jopi

+

# *** empty log message ***

+

#

+

#

+


+

 Note: To extract the uuencoded ML programs in this article most

+

       easily you may use e.g. "uud" by Edwin Kremer ,

+

       which extracts them all at once.

+


+


+

Documentation for the NMOS 65xx/85xx Instruction Set

+


+

        6510 Instructions by Addressing Modes

+

        6502 Registers

+

        6510/8502 Undocumented Commands

+

        Register selection for load and store

+

        Decimal mode in NMOS 6500 series

+

        6510 features

+

        Different CPU types

+

        6510 Instruction Timing

+

        How Real Programmers Acknowledge Interrupts

+

        Memory Management

+

        Autostart Code

+

        Notes

+

        References

+


+


+

6510 Instructions by Addressing Modes

+


+

off- ++++++++++ Positive ++++++++++  ---------- Negative ----------

+

set  00      20      40      60      80      a0      c0      e0      mode

+


+

+00  BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX     Impl/immed

+

+01  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir,x)

+

+02   t       t       t       t      NOP*t   LDX     NOP*t   NOP*t     ? /immed

+

+03  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    (indir,x)

+

+04  NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX     Zeropage

+

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

+

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

+

+07  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Zeropage

+


+

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

+

+09  ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC     Immediate

+

+0a  ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP     Accu/impl

+

+0b  ANC**   ANC**   ASR**   ARR**   ANE**   LXA**   SBX**   SBC*    Immediate

+

+0c  NOP*    BIT     JMP     JMP ()  STY     LDY     CPY     CPX     Absolute

+

+0d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute

+

+0e  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Absolute

+

+0f  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Absolute

+


+

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

+

+11  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir),y

+

+12   t       t       t       t       t       t       t       t         ?

+

+13  SLO*    RLA*    SRE*    RRA*    SHA**   LAX*    DCP*    ISB*    (indir),y

+

+14  NOP*    NOP*    NOP*    NOP*    STY     LDY     NOP*    NOP*    Zeropage,x

+

+15  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage,x

+

+16  ASL     ROL     LSR     ROR     STX  y) LDX  y) DEC     INC     Zeropage,x

+

+17  SLO*    RLA*    SRE*    RRA*    SAX* y) LAX* y) DCP*    ISB*    Zeropage,x

+


+

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

+

+19  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,y

+

+1a  NOP*    NOP*    NOP*    NOP*    TXS     TSX     NOP*    NOP*    Implied

+

+1b  SLO*    RLA*    SRE*    RRA*    SHS**   LAS**   DCP*    ISB*    Absolute,y

+

+1c  NOP*    NOP*    NOP*    NOP*    SHY**   LDY     NOP*    NOP*    Absolute,x

+

+1d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,x

+

+1e  ASL     ROL     LSR     ROR     SHX**y) LDX  y) DEC     INC     Absolute,x

+

+1f  SLO*    RLA*    SRE*    RRA*    SHA**y) LAX* y) DCP*    ISB*    Absolute,x

+


+

        ROR intruction is available on MC650x microprocessors after

+

        June, 1976.

+


+

        Legend:

+


+

        t       Jams the machine

+

        *t      Jams very rarely

+

        *       Undocumented command

+

        **      Unusual operation

+

        y)      indexed using Y instead of X

+

        ()      indirect instead of absolute

+


+

Note that the NOP instructions do have other addressing modes than the

+

implied addressing. The NOP instruction is just like any other load

+

instruction, except it does not store the result anywhere nor affects the

+

flags.

+


+

6502 Registers

+


+

The NMOS 65xx processors are not ruined with too many registers. In addition

+

to that, the registers are mostly 8-bit. Here is a brief description of each

+

register:

+


+

     PC Program Counter

+

          This register points the address from which the next instruction

+

          byte (opcode or parameter) will be fetched. Unlike other

+

          registers, this one is 16 bits in length. The low and high 8-bit

+

          halves of the register are called PCL and PCH, respectively. The

+

          Program Counter may be read by pushing its value on the stack.

+

          This can be done either by jumping to a subroutine or by causing

+

          an interrupt.

+

     S Stack pointer

+

          The NMOS 65xx processors have 256 bytes of stack memory, ranging

+

          from $0100 to $01FF. The S register is a 8-bit offset to the stack

+

          page. In other words, whenever anything is being pushed on the

+

          stack, it will be stored to the address $0100+S.

+


+

          The Stack pointer can be read and written by transfering its value

+

          to or from the index register X (see below) with the TSX and TXS

+

          instructions.

+

     P Processor status

+

          This 8-bit register stores the state of the processor. The bits in

+

          this register are called flags. Most of the flags have something

+

          to do with arithmetic operations.

+


+

          The P register can be read by pushing it on the stack (with PHP or

+

          by causing an interrupt). If you only need to read one flag, you

+

          can use the branch instructions. Setting the flags is possible by

+

          pulling the P register from stack or by using the flag set or

+

          clear instructions.

+


+

          Following is a list of the flags, starting from the 8th bit of the

+

          P register (bit 7, value $80):

+

               N Negative flag

+

                    This flag will be set after any arithmetic operations

+

                    (when any of the registers A, X or Y is being loaded

+

                    with a value). Generally, the N flag will be copied from

+

                    the topmost bit of the register being loaded.

+


+

                    Note that TXS (Transfer X to S) is not an arithmetic

+

                    operation. Also note that the BIT instruction affects

+

                    the Negative flag just like arithmetic operations.

+

                    Finally, the Negative flag behaves differently in

+

                    Decimal operations (see description below).

+

               V oVerflow flag

+

                    Like the Negative flag, this flag is intended to be used

+

                    with 8-bit signed integer numbers. The flag will be

+

                    affected by addition and subtraction, the instructions

+

                    PLP, CLV and BIT, and the hardware signal -SO. Note that

+

                    there is no SEV instruction, even though the MOS

+

                    engineers loved to use East European abbreviations, like

+

                    DDR (Deutsche Demokratische Republik vs. Data Direction

+

                    Register). (The Russian abbreviation for their former

+

                    trade association COMECON is SEV.) The -SO (Set

+

                    Overflow) signal is available on some processors, at

+

                    least the 6502, to set the V flag. This enables response

+

                    to an I/O activity in equal or less than three clock

+

                    cycles when using a BVC instruction branching to itself

+

                    ($50 $FE).

+


+

                    The CLV instruction clears the V flag, and the PLP and

+

                    BIT instructions copy the flag value from the bit 6 of

+

                    the topmost stack entry or from memory.

+


+

                    After a binary addition or subtraction, the V flag will

+

                    be set on a sign overflow, cleared otherwise. What is a

+

                    sign overflow? For instance, if you are trying to add

+

                    123 and 45 together, the result (168) does not fit in a

+

                    8-bit signed integer (upper limit 127 and lower limit

+

                    -128). Similarly, adding -123 to -45 causes the

+

                    overflow, just like subtracting -45 from 123 or 123 from

+

                    -45 would do.

+


+

                    Like the N flag, the V flag will not be set as expected

+

                    in the Decimal mode. Later in this document is a precise

+

                    operation description.

+


+

                    A common misbelief is that the V flag could only be set

+

                    by arithmetic operations, not cleared.

+

               1 unused flag

+

                    To the current knowledge, this flag is always 1.

+

               B Break flag

+

                    This flag is used to distinguish software (BRK)

+

                    interrupts from hardware interrupts (IRQ or NMI). The B

+

                    flag is always set except when the P register is being

+

                    pushed on stack when jumping to an interrupt routine to

+

                    process only a hardware interrupt.

+


+

                    The official NMOS 65xx documentation claims that the BRK

+

                    instruction could only cause a jump to the IRQ vector

+

                    ($FFFE). However, if an NMI interrupt occurs while

+

                    executing a BRK instruction, the processor will jump to

+

                    the NMI vector ($FFFA), and the P register will be

+

                    pushed on the stack with the B flag set.

+

               D Decimal mode flag

+

                    This flag is used to select the (Binary Coded) Decimal

+

                    mode for addition and subtraction. In most applications,

+

                    the flag is zero.

+


+

                    The Decimal mode has many oddities, and it operates

+

                    differently on CMOS processors. See the description of

+

                    the ADC, SBC and ARR instructions below.

+

               I Interrupt disable flag

+

                    This flag can be used to prevent the processor from

+

                    jumping to the IRQ handler vector ($FFFE) whenever the

+

                    hardware line -IRQ is active. The flag will be

+

                    automatically set after taking an interrupt, so that the

+

                    processor would not keep jumping to the interrupt

+

                    routine if the -IRQ signal remains low for several clock

+

                    cycles.

+

               Z Zero flag

+

                    The Zero flag will be affected in the same cases than

+

                    the Negative flag. Generally, it will be set if an

+

                    arithmetic register is being loaded with the value zero,

+

                    and cleared otherwise. The flag will behave differently

+

                    in Decimal operations.

+

               C Carry flag

+

                    This flag is used in additions, subtractions,

+

                    comparisons and bit rotations. In additions and

+

                    subtractions, it acts as a 9th bit and lets you to chain

+

                    operations to calculate with bigger than 8-bit numbers.

+

                    When subtracting, the Carry flag is the negative of

+

                    Borrow: if an overflow occurs, the flag will be clear,

+

                    otherwise set. Comparisons are a special case of

+

                    subtraction: they assume Carry flag set and Decimal flag

+

                    clear, and do not store the result of the subtraction

+

                    anywhere.

+


+

                    There are four kinds of bit rotations. All of them store

+

                    the bit that is being rotated off to the Carry flag. The

+

                    left shifting instructions are ROL and ASL. ROL copies

+

                    the initial Carry flag to the lowmost bit of the byte;

+

                    ASL always clears it. Similarly, the ROR and LSR

+

                    instructions shift to the right.

+

     A Accumulator

+

          The accumulator is the main register for arithmetic and logic

+

          operations. Unlike the index registers X and Y, it has a direct

+

          connection to the Arithmetic and Logic Unit (ALU). This is why

+

          many operations are only available for the accumulator, not the

+

          index registers.

+

     X Index register X

+

          This is the main register for addressing data with indices. It has

+

          a special addressing mode, indexed indirect, which lets you to

+

          have a vector table on the zero page.

+

     Y Index register Y

+

          The Y register has the least operations available. On the other

+

          hand, only it has the indirect indexed addressing mode that

+

          enables access to any memory place without having to use

+

          self-modifying code.

+


+

6510/8502 Undocumented Commands

+


+

-- A brief explanation about what may happen while using don't care states.

+


+

        ANE $8B         A = (A | #$EE) & X & #byte

+

                        same as

+

                        A = ((A & #$11 & X) | ( #$EE & X)) & #byte

+


+

                        In real 6510/8502 the internal parameter #$11

+

                        may occasionally be #$10, #$01 or even #$00.

+

                        This occurs when the video chip starts DMA

+

                        between the opcode fetch and the parameter fetch

+

                        of the instruction.  The value probably depends

+

                        on the data that was left on the bus by the VIC-II.

+


+

        LXA $AB         C=Lehti:   A = X = ANE

+

                        Alternate: A = X = (A & #byte)

+


+

                        TXA and TAX have to be responsible for these.

+


+

        SHA $93,$9F     Store (A & X & (ADDR_HI + 1))

+

        SHX $9E         Store (X & (ADDR_HI + 1))

+

        SHY $9C         Store (Y & (ADDR_HI + 1))

+

        SHS $9B         SHA and TXS, where X is replaced by (A & X).

+


+

                        Note: The value to be stored is copied also

+

                        to ADDR_HI if page boundary is crossed.

+


+

        SBX $CB         Carry and Decimal flags are ignored but the

+

                        Carry flag will be set in substraction. This

+

                        is due to the CMP command, which is executed

+

                        instead of the real SBC.

+


+

        ARR $6B         This instruction first performs an AND

+

                        between the accumulator and the immediate

+

                        parameter, then it shifts the accumulator to

+

                        the right. However, this is not the whole

+

                        truth. See the description below.

+


+

Many undocumented commands do not use AND between registers, the CPU

+

just throws the bytes to a bus simultaneously and lets the

+

open-collector drivers perform the AND. I.e. the command called 'SAX',

+

which is in the STORE section (opcodes $A0...$BF), stores the result

+

of (A & X) by this way.

+


+

More fortunate is its opposite, 'LAX' which just loads a byte

+

simultaneously into both A and X.

+


+

        $6B  ARR

+


+

This instruction seems to be a harmless combination of AND and ROR at

+

first sight, but it turns out that it affects the V flag and also has

+

a special kind of decimal mode. This is because the instruction has

+

inherited some properties of the ADC instruction ($69) in addition to

+

the ROR ($6A).

+


+

In Binary mode (D flag clear), the instruction effectively does an AND

+

between the accumulator and the immediate parameter, and then shifts

+

the accumulator to the right, copying the C flag to the 8th bit. It

+

sets the Negative and Zero flags just like the ROR would. The ADC code

+

shows up in the Carry and oVerflow flags. The C flag will be copied

+

from the bit 6 of the result (which doesn't seem too logical), and the

+

V flag is the result of an Exclusive OR operation between the bit 6

+

and the bit 5 of the result.  This makes sense, since the V flag will

+

be normally set by an Exclusive OR, too.

+


+

In Decimal mode (D flag set), the ARR instruction first performs the

+

AND and ROR, just like in Binary mode. The N flag will be copied from

+

the initial C flag, and the Z flag will be set according to the ROR

+

result, as expected. The V flag will be set if the bit 6 of the

+

accumulator changed its state between the AND and the ROR, cleared

+

otherwise.

+


+

Now comes the funny part. If the low nybble of the AND result,

+

incremented by its lowmost bit, is greater than 5, the low nybble in

+

the ROR result will be incremented by 6. The low nybble may overflow

+

as a consequence of this BCD fixup, but the high nybble won't be

+

adjusted. The high nybble will be BCD fixed in a similar way. If the

+

high nybble of the AND result, incremented by its lowmost bit, is

+

greater than 5, the high nybble in the ROR result will be incremented

+

by 6, and the Carry flag will be set. Otherwise the C flag will be

+

cleared.

+


+

To help you understand this description, here is a C routine that

+

illustrates the ARR operation in Decimal mode:

+


+

        unsigned

+

           A,  /* Accumulator */

+

           AL, /* low nybble of accumulator */

+

           AH, /* high nybble of accumulator */

+


+

           C,  /* Carry flag */

+

           Z,  /* Zero flag */

+

           V,  /* oVerflow flag */

+

           N,  /* Negative flag */

+


+

           t,  /* temporary value */

+

           s;  /* value to be ARRed with Accumulator */

+


+

        t = A & s;                      /* Perform the AND. */

+


+

        AH = t >> 4;                    /* Separate the high */

+

        AL = t & 15;                    /* and low nybbles. */

+


+

        N = C;                          /* Set the N and */

+

        Z = !(A = (t >> 1) | (C << 7)); /* Z flags traditionally */

+

        V = (t ^ A) & 64;               /* and V flag in a weird way. */

+


+

        if (AL + (AL & 1) > 5)          /* BCD "fixup" for low nybble. */

+

          A = (A & 0xF0) | ((A + 6) & 0xF);

+


+

        if (C = AH + (AH & 1) > 5)      /* Set the Carry flag. */

+

          A = (A + 0x60) & 0xFF;        /* BCD "fixup" for high nybble. */

+


+

        $CB  SBX   X <- (A & X) - Immediate

+


+

The 'SBX' ($CB) may seem to be very complex operation, even though it

+

is a combination of the subtraction of accumulator and parameter, as

+

in the 'CMP' instruction, and the command 'DEX'. As a result, both A

+

and X are connected to ALU but only the subtraction takes place. Since

+

the comparison logic was used, the result of subtraction should be

+

normally ignored, but the 'DEX' now happily stores to X the value of

+

(A & X) - Immediate.  That is why this instruction does not have any

+

decimal mode, and it does not affect the V flag. Also Carry flag will

+

be ignored in the subtraction but set according to the result.

+


+

 Proof:

+


+

begin 644 vsbx

+

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```*D`H#V1*Z`_D2N@09$KJ0>%

+

M^QBE^VEZJ+$KH#F1*ZD`2"BI`*(`RP`(:-B@.5$K*4#P`E@`H#VQ*SAI`)$K

+

JD-Z@/[$K:0"1*Y#4J2X@TO\XH$&Q*VD`D2N0Q,;[$+188/_^]_:_OK>V

+

`

+

end

+


+

 and

+


+

begin 644 sbx

+

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI`*!-D2N@3Y$KH%&1*ZD#

+

MA?L8I?M*2)`#J1@LJ3B@29$K:$J0`ZGX+*G8R)$K&/BXJ?2B8\L)AOP(:(7]

+

MV#B@3;$KH$\Q*Z!1\2L(1?SP`0!H1?TIM]#XH$VQ*SAI`)$KD,N@3[$K:0"1

+

9*Y#!J2X@TO\XH%&Q*VD`D2N0L<;[$))88-#X

+

`

+

end

+


+

These test programs show if your machine is compatible with ours

+

regarding the opcode $CB. The first test, vsbx, proves that SBX does

+

not affect the V flag. The latter one, sbx, proves the rest of our

+

theory. The vsbx test tests 33554432 SBX combinations (16777216

+

different A, X and Immediate combinations, and two different V flag

+

states), and the sbx test doubles that amount (16777216*4 D and C flag

+

combinations). Both tests have run successfully on a C64 and a Vic20.

+

They ought to run on C16, +4 and the PET series as well. The tests

+

stop with BRK, if the opcode $CB does not work as expected. Successful

+

operation ends in RTS. As the tests are very slow, they print dots on

+

the screen while running so that you know that the machine has not

+

jammed. On computers running at 1 MHz, the first test prints

+

approximately one dot every four seconds and a total of 2048 dots,

+

whereas the second one prints half that amount, one dot every seven

+

seconds.

+


+

If the tests fail on your machine, please let us know your processor's

+

part number and revision. If possible, save the executable (after it

+

has stopped with BRK) under another name and send it to us so that we

+

know at which stage the program stopped.

+


+

The following program is a Commodore 64 executable that Marko M"akel"a

+

developed when trying to find out how the V flag is affected by SBX.

+

(It was believed that the SBX affects the flag in a weird way, and

+

this program shows how SBX sets the flag differently from SBC.)  You

+

may find the subroutine at $C150 useful when researching other

+

undocumented instructions' flags. Run the program in a machine

+

language monitor, as it makes use of the BRK instruction. The result

+

tables will be written on pages $C2 and $C3.

+


+

begin 644 sbx-c100

+

M`,%XH`",#L&,$,&,$L&XJ8*B@LL7AOL(:(7\N#BM#L$M$,'M$L$(Q?OP`B@`

+

M:$7\\`,@4,'N#L'0U.X0P=#/SB#0[A+!T,<``````````````)BJ\!>M#L$M

+

L$,'=_\'0":T2P=W_PM`!8,K0Z:T.P2T0P9D`PID`!*T2P9D`PYD`!

+


+

Other undocumented instructions usually cause two preceding opcodes

+

being executed. However 'NOP' seems to completely disappear from 'SBC'

+

code $EB.

+


+

The most difficult to comprehend are the rest of the instructions

+

located on the '$0B' line.

+


+

All the instructions located at the positive (left) side of this line

+

should rotate either memory or the accumulator, but the addressing

+

mode turns out to be immediate! No problem. Just read the operand, let

+

it be ANDed with the accumulator and finally use accumulator

+

addressing mode for the instructions above them.

+


+

RELIGION_MODE_ON

+

/* This part of the document is not accurate.  You can

+

   read it as a fairy tale, but do not count on it when

+

   performing your own measurements. */

+


+

The rest two instructions on the same line, called 'ANE' and 'LXA'

+

($8B and $AB respectively) often give quite unpredictable results.

+

However, the most usual operation is to store ((A | #$ee) & X & #$nn)

+

to accumulator. Note that this does not work reliably in a real 64!

+

In the Commodore 128 the opcode $8B uses values 8C, CC, EE, and

+

occasionally 0C and 8E for the OR instead of EE,EF,FE and FF used in

+

the C64. With a C128 running at 2 MHz #$EE is always used.  Opcode $AB

+

does not cause this OR taking place on 8502 while 6510 always performs

+

it. Note that this behaviour depends on processor and/or video chip

+

revision.

+


+

Let's take a closer look at $8B (6510).

+


+

        A <- X & D & (A | VAL)

+


+

        where VAL comes from this table:

+


+

       X high   D high  D low   VAL

+

        even     even    ---    $EE (1)

+

        even     odd     ---    $EE

+

        odd      even    ---    $EE

+

        odd      odd      0     $EE

+

        odd      odd     not 0  $FE (2)

+


+

(1) If the bottom 2 bits of A are both 1, then the LSB of the result may

+

    be 0. The values of X and D are different every time I run the test.

+

    This appears to be very rare.

+

(2) VAL is $FE most of the time. Sometimes it is $EE - it seems to be random,

+

    not related to any of the data. This is much more common than (1).

+


+

  In decimal mode, VAL is usually $FE.

+


+

Two different functions have been discovered for LAX, opcode $AB. One

+

is A = X = ANE (see above) and the other, encountered with 6510 and

+

8502, is less complicated A = X = (A & #byte). However, according to

+

what is reported, the version altering only the lowest bits of each

+

nybble seems to be more common.

+


+

What happens, is that $AB loads a value into both A and X, ANDing the

+

low bit of each nybble with the corresponding bit of the old

+

A. However, there are exceptions. Sometimes the low bit is cleared

+

even when A contains a '1', and sometimes other bits are cleared. The

+

exceptions seem random (they change every time I run the test). Oops -

+

that was in decimal mode. Much the same with D=0.

+


+

What causes the randomness?  Probably it is that it is marginal logic

+

levels - when too much wired-anding goes on, some of the signals get

+

very close to the threshold. Perhaps we're seeing some of them step

+

over it. The low bit of each nybble is special, since it has to cope

+

with carry differently (remember decimal mode). We never see a '0'

+

turn into a '1'.

+


+

Since these instructions are unpredictable, they should not be used.

+


+

There is still very strange instruction left, the one named SHA/X/Y,

+

which is the only one with only indexed addressing modes. Actually,

+

the commands 'SHA', 'SHX' and 'SHY' are generated by the indexing

+

algorithm.

+


+

While using indexed addressing, effective address for page boundary

+

crossing is calculated as soon as possible so it does not slow down

+

operation. As a result, in the case of SHA/X/Y, the address and data

+

are processed at the same time making AND between them to take place.

+

Thus, the value to be stored by SAX, for example, is in fact (A & X &

+

(ADDR_HI + 1)).  On page boundary crossing the same value is copied

+

also to high byte of the effective address.

+


+

RELIGION_MODE_OFF

+


+


+

Register selection for load and store

+


+

   bit1 bit0     A  X  Y

+

    0    0             x

+

    0    1          x

+

    1    0       x

+

    1    1       x  x

+


+

So, A and X are selected by bits 1 and 0 respectively, while

+

 ~(bit1|bit0) enables Y.

+


+

Indexing is determined by bit4, even in relative addressing mode,

+

which is one kind of indexing.

+


+

Lines containing opcodes xxx000x1 (01 and 03) are treated as absolute

+

after the effective address has been loaded into CPU.

+


+

Zeropage,y and Absolute,y (codes 10x1 x11x) are distinquished by bit5.

+


+


+

Decimal mode in NMOS 6500 series

+


+

  Most sources claim that the NMOS 6500 series sets the N, V and Z

+

flags unpredictably when performing addition or subtraction in decimal

+

mode. Of course, this is not true. While testing how the flags are

+

set, I also wanted to see what happens if you use illegal BCD values.

+


+

  ADC works in Decimal mode in a quite complicated way. It is amazing

+

how it can do that all in a single cycle. Here's a C code version of

+

the instruction:

+


+

        unsigned

+

           A,  /* Accumulator */

+

           AL, /* low nybble of accumulator */

+

           AH, /* high nybble of accumulator */

+


+

           C,  /* Carry flag */

+

           Z,  /* Zero flag */

+

           V,  /* oVerflow flag */

+

           N,  /* Negative flag */

+


+

           s;  /* value to be added to Accumulator */

+


+

        AL = (A & 15) + (s & 15) + C;         /* Calculate the lower nybble. */

+


+

        AH = (A >> 4) + (s >> 4) + (AL > 15); /* Calculate the upper nybble. */

+


+

        if (AL > 9) AL += 6;                  /* BCD fixup for lower nybble. */

+


+

        Z = ((A + s + C) & 255 != 0);         /* Zero flag is set just

+

                                                 like in Binary mode. */

+


+

        /* Negative and Overflow flags are set with the same logic than in

+

           Binary mode, but after fixing the lower nybble. */

+


+

        N = (AH & 8 != 0);

+

        V = ((AH << 4) ^ A) & 128 && !((A ^ s) & 128);

+


+

        if (AH > 9) AH += 6;                  /* BCD fixup for upper nybble. */

+


+

        /* Carry is the only flag set after fixing the result. */

+


+

        C = (AH > 15);

+

        A = ((AH << 4) | (AL & 15)) & 255;

+


+

  The C flag is set as the quiche eaters expect, but the N and V flags

+

are set after fixing the lower nybble but before fixing the upper one.

+

They use the same logic than binary mode ADC. The Z flag is set before

+

any BCD fixup, so the D flag does not have any influence on it.

+


+

Proof: The following test program tests all 131072 ADC combinations in

+

       Decimal mode, and aborts with BRK if anything breaks this theory.

+

       If everything goes well, it ends in RTS.

+


+

begin 600 dadc

+

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH(V1

+

M*Q@(I?PI#X7]I?LI#V7]R0J0 FD%J"D/A?VE^RGP9?PI\ C $) ":0^JL @H

+

ML ?)H) &""@X:5\X!?V%_0AH*3W@ ! ""8"HBD7[$ JE^T7\, 28"4"H**7[

+

M9?S0!)@) J@8N/BE^V7\V A%_= G:(3]1?W0(.;[T(?F_-"#:$D8\ )88*D=

+

0&&4KA?NI &4LA?RI.&S[  A%

+


+

end

+


+

  All programs in this chapter have been successfully tested on a Vic20

+

and a Commodore 64 and a Commodore 128D in C64 mode. They should run on

+

C16, +4 and on the PET series as well. If not, please report the problem

+

to Marko M"akel"a. Each test in this chapter should run in less than a

+

minute at 1 MHz.

+


+

SBC is much easier. Just like CMP, its flags are not affected by

+

the D flag.

+


+

Proof:

+


+

begin 600 dsbc-cmp-flags

+

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'B@ (3[A/RB XH8:66HL2N@

+

M09$KH$R1*XII::BQ*Z!%D2N@4)$K^#BXI?OE_-@(:(7].+BE^^7\"&A%_? !

+

5 .;[T./F_-#?RA"_8!@X&#CEY<7%

+


+

end

+


+

  The only difference in SBC's operation in decimal mode from binary mode

+

is the result-fixup:

+


+

        unsigned

+

           A,  /* Accumulator */

+

           AL, /* low nybble of accumulator */

+

           AH, /* high nybble of accumulator */

+


+

           C,  /* Carry flag */

+

           Z,  /* Zero flag */

+

           V,  /* oVerflow flag */

+

           N,  /* Negative flag */

+


+

           s;  /* value to be added to Accumulator */

+


+

        AL = (A & 15) - (s & 15) - !C;        /* Calculate the lower nybble. */

+


+

        if (AL & 16) AL -= 6;                 /* BCD fixup for lower nybble. */

+


+

        AH = (A >> 4) - (s >> 4) - (AL & 16); /* Calculate the upper nybble. */

+


+

        if (AH & 16) AH -= 6;                 /* BCD fixup for upper nybble. */

+


+

        /* The flags are set just like in Binary mode. */

+


+

        C = (A - s - !C) & 256 != 0;

+

        Z = (A - s - !C) & 255 != 0;

+

        V = ((A - s - !C) ^ s) & 128 && (A ^ s) & 128;

+

        N = (A - s - !C) & 128 != 0;

+


+

        A = ((AH << 4) | (AL & 15)) & 255;

+


+

  Again Z flag is set before any BCD fixup. The N and V flags are set

+

at any time before fixing the high nybble. The C flag may be set in any

+

phase.

+


+

  Decimal subtraction is easier than decimal addition, as you have to

+

make the BCD fixup only when a nybble overflows. In decimal addition,

+

you had to verify if the nybble was greater than 9. The processor has

+

an internal "half carry" flag for the lower nybble, used to trigger

+

the BCD fixup. When calculating with legal BCD values, the lower nybble

+

cannot overflow again when fixing it.

+

So, the processor does not handle overflows while performing the fixup.

+

Similarly, the BCD fixup occurs in the high nybble only if the value

+

overflows, i.e. when the C flag will be cleared.

+


+

  Because SBC's flags are not affected by the Decimal mode flag, you

+

could guess that CMP uses the SBC logic, only setting the C flag

+

first. But the SBX instruction shows that CMP also temporarily clears

+

the D flag, although it is totally unnecessary.

+


+

  The following program, which tests SBC's result and flags,

+

contains the 6502 version of the pseudo code example above.

+


+

begin 600 dsbc

+

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH':1

+

M*S@(I?PI#X7]I?LI#^7]L /I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL KI7RBP

+

M#ND/.+ )*+ &Z0^P NE?A/T%_87]*+BE^^7\"&BH.+CXI?OE_-@(1?W0FVB$

+

8_47]T)3F^]">YOS0FFA)&- $J3C0B%A@

+


+

end

+


+

  Obviously the undocumented instructions RRA (ROR+ADC) and ISB

+

(INC+SBC) have inherited also the decimal operation from the official

+

instructions ADC and SBC. The program droradc proves this statement

+

for ROR, and the dincsbc test proves this for ISB. Finally,

+

dincsbc-deccmp proves that ISB's and DCP's (DEC+CMP) flags are not

+

affected by the D flag.

+


+

begin 644 droradc

+

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH(V1

+

M*S@(I?PI#X7]I?LI#V7]R0J0`FD%J"D/A?VE^RGP9?PI\`C`$)`":0^JL`@H

+

ML`?)H)`&""@X:5\X!?V%_0AH*3W@`!`""8"HBD7[$`JE^T7\,`28"4"H**7[

+

M9?S0!)@)`J@XN/BE^R;\9_S8"$7]T"=HA/U%_=`@YOO0A>;\T(%H21CP`EA@

+

2J1T892N%^ZD`92R%_*DX;/L`

+

`

+

end

+


+

begin 644 dincsbc

+

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH':1

+

M*S@(I?PI#X7]I?LI#^7]L`/I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL`KI7RBP

+

M#ND/.+`)*+`&Z0^P`NE?A/T%_87]*+BE^^7\"&BH.+CXI?O&_.?\V`A%_="9

+

::(3]1?W0DN;[T)SF_-"8:$D8T`2I.-"&6&#\

+

`

+

end

+


+

begin 644 dincsbc-deccmp

+

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'B@`(3[A/RB`XH8:7>HL2N@

+

M3Y$KH%R1*XII>ZBQ*Z!3D2N@8)$KBFE_J+$KH%61*Z!BD2OX.+BE^^;\Q_S8

+

L"&B%_3BXI?OF_,?\"&A%_?`!`.;[T-_F_-#;RA"M8!@X&#CFYL;&Q\?GYP#8

+

`

+

end

+


+


+

6510 features

+


+

   o  PHP always pushes the Break (B) flag as a `1' to the stack.

+

      Jukka Tapanim"aki claimed in C=lehti issue 3/89, on page 27 that the

+

      processor makes a logical OR between the status register's bit 4

+

      and the bit 8 of the stack pointer register (which is always 1).

+

      He did not give any reasons for this argument, and has refused to clarify

+

      it afterwards. Well, this was not the only error in his article...

+


+

   o  Indirect addressing modes do not handle page boundary crossing at all.

+

      When the parameter's low byte is $FF, the effective address wraps

+

      around and the CPU fetches high byte from $xx00 instead of $xx00+$0100.

+

      E.g. JMP ($01FF) fetches PCL from $01FF and PCH from $0100,

+

      and LDA ($FF),Y fetches the base address from $FF and $00.

+


+

   o  Indexed zero page addressing modes never fix the page address on

+

      crossing the zero page boundary.

+

      E.g. LDX #$01 : LDA ($FF,X) loads the effective address from $00 and $01.

+


+

   o  The processor always fetches the byte following a relative branch

+

      instruction. If the branch is taken, the processor reads then the

+

      opcode from the destination address. If page boundary is crossed, it

+

      first reads a byte from the old page from a location that is bigger

+

      or smaller than the correct address by one page.

+


+

   o  If you cross a page boundary in any other indexed mode,

+

      the processor reads an incorrect location first, a location that is

+

      smaller by one page.

+


+

   o  Read-Modify-Write instructions write unmodified data, then modified

+

      (so INC effectively does LDX loc;STX loc;INX;STX loc)

+


+

   o  -RDY is ignored during writes

+

      (This is why you must wait 3 cycles before doing any DMA --

+

      the maximum number of consecutive writes is 3, which occurs

+

      during interrupts except -RESET.)

+


+

   o  Some undefined opcodes may give really unpredictable results.

+


+

   o  All registers except the Program Counter remain unmodified after -RESET.

+

      (This is why you must preset D and I flags in the RESET handler.)

+


+


+

Different CPU types

+


+

The Rockwell data booklet 29651N52 (technical information about R65C00

+

microprocessors, dated October 1984), lists the following differences between

+

NMOS R6502 microprocessor and CMOS R65C00 family:

+


+


+

     1. Indexed addressing across page boundary.

+

             NMOS: Extra read of invalid address.

+

             CMOS: Extra read of last instruction byte.

+


+


+

     2. Execution of invalid op codes.

+

             NMOS: Some terminate only by reset. Results are undefined.

+

             CMOS: All are NOPs (reserved for future use).

+


+


+

     3. Jump indirect, operand = XXFF.

+

             NMOS: Page address does not increment.

+

             CMOS: Page address increments and adds one additional cycle.

+


+


+

     4. Read/modify/write instructions at effective address.

+

             NMOS: One read and two write cycles.

+

             CMOS: Two read and one write cycle.

+


+


+

     5. Decimal flag.

+

             NMOS: Indeterminate after reset.

+

             CMOS: Initialized to binary mode (D=0) after reset and interrupts.

+


+


+

     6. Flags after decimal operation.

+

             NMOS: Invalid N, V and Z flags.

+

             CMOS: Valid flag adds one additional cycle.

+


+


+

     7. Interrupt after fetch of BRK instruction.

+

             NMOS: Interrupt vector is loaded, BRK vector is ignored.

+

             CMOS: BRK is executed, then interrupt is executed.

+


+


+

6510 Instruction Timing

+


+

  The NMOS 6500 series processors always perform at least two reads

+

for each instruction. In addition to the operation code (opcode), they

+

fetch the next byte. This is quite efficient, as most instructions are

+

two or three bytes long.

+


+

  The processors also use a sort of pipelining. If an instruction does

+

not store data in memory on its last cycle, the processor can fetch

+

the opcode of the next instruction while executing the last cycle. For

+

instance, the instruction EOR #$FF truly takes three cycles. On the

+

first cycle, the opcode $49 will be fetched. During the second cycle

+

the processor decodes the opcode and fetches the parameter #$FF. On

+

the third cycle, the processor will perform the operation and store

+

the result to accumulator, but simultaneously it fetches the opcode

+

for the next instruction. This is why the instruction effectively

+

takes only two cycles.

+


+

  The following tables show what happens on the bus while executing

+

different kinds of instructions.

+


+

  Interrupts

+


+

     NMI and IRQ both take 7 cycles. Their timing diagram is much like

+

     BRK's (see below). IRQ will be executed only when the I flag is

+

     clear. IRQ and BRK both set the I flag, whereas the NMI does not

+

     affect its state.

+


+

     The processor will usually wait for the current instruction to

+

     complete before executing the interrupt sequence. To process the

+

     interrupt before the next instruction, the interrupt must occur

+

     before the last cycle of the current instruction.

+


+

     There is one exception to this rule: the BRK instruction. If a

+

     hardware interrupt (NMI or IRQ) occurs before the fourth (flags

+

     saving) cycle of BRK, the BRK instruction will be skipped, and

+

     the processor will jump to the hardware interrupt vector. This

+

     sequence will always take 7 cycles.

+


+

     You do not completely lose the BRK interrupt, the B flag will be

+

     set in the pushed status register if a BRK instruction gets

+

     interrupted. When BRK and IRQ occur at the same time, this does

+

     not cause any problems, as your program will consider it as a

+

     BRK, and the IRQ would occur again after the processor returned

+

     from your BRK routine, unless you cleared the interrupt source in

+

     your BRK handler. But the simultaneous occurrence of NMI and BRK

+

     is far more fatal. If you do not check the B flag in the NMI

+

     routine and subtract two from the return address when needed, the

+

     BRK instruction will be skipped.

+


+

     If the NMI and IRQ interrupts overlap each other (one interrupt

+

     occurs before fetching the interrupt vector for the other

+

     interrupt), the processor will most probably jump to the NMI

+

     vector in every case, and then jump to the IRQ vector after

+

     processing the first instruction of the NMI handler. This has not

+

     been measured yet, but the IRQ is very similar to BRK, and many

+

     sources state that the NMI has higher priority than IRQ. However,

+

     it might be that the processor takes the interrupt that comes

+

     later, i.e. you could lose an NMI interrupt if an IRQ occurred in

+

     four cycles after it.

+


+

     After finishing the interrupt sequence, the processor will start

+

     to execute the first instruction of the interrupt routine. This

+

     proves that the processor uses a sort of pipelining: it finishes

+

     the current instruction (or interrupt sequence) while reading the

+

     opcode of the next instruction.

+


+

     RESET does not push program counter on stack, and it lasts

+

     probably 6 cycles after deactivating the signal. Like NMI, RESET

+

     preserves all registers except PC.

+


+

  Instructions accessing the stack

+


+

     BRK

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  read next instruction byte (and throw it away),

+

                       increment PC

+

        3  $0100,S  W  push PCH on stack (with B flag set), decrement S

+

        4  $0100,S  W  push PCL on stack, decrement S

+

        5  $0100,S  W  push P on stack, decrement S

+

        6   $FFFE   R  fetch PCL

+

        7   $FFFF   R  fetch PCH

+


+

     RTI

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  read next instruction byte (and throw it away)

+

        3  $0100,S  R  increment S

+

        4  $0100,S  R  pull P from stack, increment S

+

        5  $0100,S  R  pull PCL from stack, increment S

+

        6  $0100,S  R  pull PCH from stack

+


+

     RTS

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  read next instruction byte (and throw it away)

+

        3  $0100,S  R  increment S

+

        4  $0100,S  R  pull PCL from stack, increment S

+

        5  $0100,S  R  pull PCH from stack

+

        6    PC     R  increment PC

+


+

     PHA, PHP

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  read next instruction byte (and throw it away)

+

        3  $0100,S  W  push register on stack, decrement S

+


+

     PLA, PLP

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  read next instruction byte (and throw it away)

+

        3  $0100,S  R  increment S

+

        4  $0100,S  R  pull register from stack

+


+

     JSR

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch low address byte, increment PC

+

        3  $0100,S  R  internal operation (predecrement S?)

+

        4  $0100,S  W  push PCH on stack, decrement S

+

        5  $0100,S  W  push PCL on stack, decrement S

+

        6    PC     R  copy low address byte to PCL, fetch high address

+

                       byte to PCH

+


+

  Accumulator or implied addressing

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  read next instruction byte (and throw it away)

+


+

  Immediate addressing

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch value, increment PC

+


+

  Absolute addressing

+


+

     JMP

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch low address byte, increment PC

+

        3    PC     R  copy low address byte to PCL, fetch high address

+

                       byte to PCH

+


+

     Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                        LAX, NOP)

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch low byte of address, increment PC

+

        3    PC     R  fetch high byte of address, increment PC

+

        4  address  R  read from effective address

+


+

     Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                     SLO, SRE, RLA, RRA, ISB, DCP)

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch low byte of address, increment PC

+

        3    PC     R  fetch high byte of address, increment PC

+

        4  address  R  read from effective address

+

        5  address  W  write the value back to effective address,

+

                       and do the operation on it

+

        6  address  W  write the new value to effective address

+


+

     Write instructions (STA, STX, STY, SAX)

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch low byte of address, increment PC

+

        3    PC     R  fetch high byte of address, increment PC

+

        4  address  W  write register to effective address

+


+

  Zero page addressing

+


+

     Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                        LAX, NOP)

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch address, increment PC

+

        3  address  R  read from effective address

+


+

     Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                     SLO, SRE, RLA, RRA, ISB, DCP)

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch address, increment PC

+

        3  address  R  read from effective address

+

        4  address  W  write the value back to effective address,

+

                       and do the operation on it

+

        5  address  W  write the new value to effective address

+


+

     Write instructions (STA, STX, STY, SAX)

+


+

        #  address R/W description

+

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

+

        1    PC     R  fetch opcode, increment PC

+

        2    PC     R  fetch address, increment PC

+

        3  address  W  write register to effective address

+


+

  Zero page indexed addressing

+


+

     Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                        LAX, NOP)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch address, increment PC

+

        3   address   R  read from address, add index register to it

+

        4  address+I* R  read from effective address

+


+

       Notes: I denotes either index register (X or Y).

+


+

              * The high byte of the effective address is always zero,

+

                i.e. page boundary crossings are not handled.

+


+

     Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                     SLO, SRE, RLA, RRA, ISB, DCP)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch address, increment PC

+

        3   address   R  read from address, add index register X to it

+

        4  address+X* R  read from effective address

+

        5  address+X* W  write the value back to effective address,

+

                         and do the operation on it

+

        6  address+X* W  write the new value to effective address

+


+

       Note: * The high byte of the effective address is always zero,

+

               i.e. page boundary crossings are not handled.

+


+

     Write instructions (STA, STX, STY, SAX)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch address, increment PC

+

        3   address   R  read from address, add index register to it

+

        4  address+I* W  write to effective address

+


+

       Notes: I denotes either index register (X or Y).

+


+

              * The high byte of the effective address is always zero,

+

                i.e. page boundary crossings are not handled.

+


+

  Absolute indexed addressing

+


+

     Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                        LAX, LAE, SHS, NOP)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch low byte of address, increment PC

+

        3     PC      R  fetch high byte of address,

+

                         add index register to low address byte,

+

                         increment PC

+

        4  address+I* R  read from effective address,

+

                         fix the high byte of effective address

+

        5+ address+I  R  re-read from effective address

+


+

       Notes: I denotes either index register (X or Y).

+


+

              * The high byte of the effective address may be invalid

+

                at this time, i.e. it may be smaller by $100.

+


+

              + This cycle will be executed only if the effective address

+

                was invalid during cycle #4, i.e. page boundary was crossed.

+


+

     Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                     SLO, SRE, RLA, RRA, ISB, DCP)

+


+

        #   address  R/W description

+

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

+

        1    PC       R  fetch opcode, increment PC

+

        2    PC       R  fetch low byte of address, increment PC

+

        3    PC       R  fetch high byte of address,

+

                         add index register X to low address byte,

+

                         increment PC

+

        4  address+X* R  read from effective address,

+

                         fix the high byte of effective address

+

        5  address+X  R  re-read from effective address

+

        6  address+X  W  write the value back to effective address,

+

                         and do the operation on it

+

        7  address+X  W  write the new value to effective address

+


+

       Notes: * The high byte of the effective address may be invalid

+

                at this time, i.e. it may be smaller by $100.

+


+

     Write instructions (STA, STX, STY, SHA, SHX, SHY)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch low byte of address, increment PC

+

        3     PC      R  fetch high byte of address,

+

                         add index register to low address byte,

+

                         increment PC

+

        4  address+I* R  read from effective address,

+

                         fix the high byte of effective address

+

        5  address+I  W  write to effective address

+


+

       Notes: I denotes either index register (X or Y).

+


+

              * The high byte of the effective address may be invalid

+

                at this time, i.e. it may be smaller by $100. Because

+

                the processor cannot undo a write to an invalid

+

                address, it always reads from the address first.

+


+

  Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch operand, increment PC

+

        3     PC      R  Fetch opcode of next instruction,

+

                         If branch is taken, add operand to PCL.

+

                         Otherwise increment PC.

+

        4+    PC*     R  Fetch opcode of next instruction.

+

                         Fix PCH. If it did not change, increment PC.

+

        5!    PC      R  Fetch opcode of next instruction,

+

                         increment PC.

+


+

       Notes: The opcode fetch of the next instruction is included to

+

              this diagram for illustration purposes. When determining

+

              real execution times, remember to subtract the last

+

              cycle.

+


+

              * The high byte of Program Counter (PCH) may be invalid

+

                at this time, i.e. it may be smaller or bigger by $100.

+


+

              + If branch is taken, this cycle will be executed.

+


+

              ! If branch occurs to different page, this cycle will be

+

                executed.

+


+

  Indexed indirect addressing

+


+

     Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX)

+


+

        #    address   R/W description

+

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

+

        1      PC       R  fetch opcode, increment PC

+

        2      PC       R  fetch pointer address, increment PC

+

        3    pointer    R  read from the address, add X to it

+

        4   pointer+X   R  fetch effective address low

+

        5  pointer+X+1  R  fetch effective address high

+

        6    address    R  read from effective address

+


+

       Note: The effective address is always fetched from zero page,

+

             i.e. the zero page boundary crossing is not handled.

+


+

     Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

+


+

        #    address   R/W description

+

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

+

        1      PC       R  fetch opcode, increment PC

+

        2      PC       R  fetch pointer address, increment PC

+

        3    pointer    R  read from the address, add X to it

+

        4   pointer+X   R  fetch effective address low

+

        5  pointer+X+1  R  fetch effective address high

+

        6    address    R  read from effective address

+

        7    address    W  write the value back to effective address,

+

                           and do the operation on it

+

        8    address    W  write the new value to effective address

+


+

       Note: The effective address is always fetched from zero page,

+

             i.e. the zero page boundary crossing is not handled.

+


+

     Write instructions (STA, SAX)

+


+

        #    address   R/W description

+

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

+

        1      PC       R  fetch opcode, increment PC

+

        2      PC       R  fetch pointer address, increment PC

+

        3    pointer    R  read from the address, add X to it

+

        4   pointer+X   R  fetch effective address low

+

        5  pointer+X+1  R  fetch effective address high

+

        6    address    W  write to effective address

+


+

       Note: The effective address is always fetched from zero page,

+

             i.e. the zero page boundary crossing is not handled.

+


+

  Indirect indexed addressing

+


+

     Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP)

+


+

        #    address   R/W description

+

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

+

        1      PC       R  fetch opcode, increment PC

+

        2      PC       R  fetch pointer address, increment PC

+

        3    pointer    R  fetch effective address low

+

        4   pointer+1   R  fetch effective address high,

+

                           add Y to low byte of effective address

+

        5   address+Y*  R  read from effective address,

+

                           fix high byte of effective address

+

        6+  address+Y   R  read from effective address

+


+

       Notes: The effective address is always fetched from zero page,

+

              i.e. the zero page boundary crossing is not handled.

+


+

              * The high byte of the effective address may be invalid

+

                at this time, i.e. it may be smaller by $100.

+


+

              + This cycle will be executed only if the effective address

+

                was invalid during cycle #5, i.e. page boundary was crossed.

+


+

     Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

+


+

        #    address   R/W description

+

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

+

        1      PC       R  fetch opcode, increment PC

+

        2      PC       R  fetch pointer address, increment PC

+

        3    pointer    R  fetch effective address low

+

        4   pointer+1   R  fetch effective address high,

+

                           add Y to low byte of effective address

+

        5   address+Y*  R  read from effective address,

+

                           fix high byte of effective address

+

        6   address+Y   R  read from effective address

+

        7   address+Y   W  write the value back to effective address,

+

                           and do the operation on it

+

        8   address+Y   W  write the new value to effective address

+


+

       Notes: The effective address is always fetched from zero page,

+

              i.e. the zero page boundary crossing is not handled.

+


+

              * The high byte of the effective address may be invalid

+

                at this time, i.e. it may be smaller by $100.

+


+

     Write instructions (STA, SHA)

+


+

        #    address   R/W description

+

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

+

        1      PC       R  fetch opcode, increment PC

+

        2      PC       R  fetch pointer address, increment PC

+

        3    pointer    R  fetch effective address low

+

        4   pointer+1   R  fetch effective address high,

+

                           add Y to low byte of effective address

+

        5   address+Y*  R  read from effective address,

+

                           fix high byte of effective address

+

        6   address+Y   W  write to effective address

+


+

       Notes: The effective address is always fetched from zero page,

+

              i.e. the zero page boundary crossing is not handled.

+


+

              * The high byte of the effective address may be invalid

+

                at this time, i.e. it may be smaller by $100.

+


+

  Absolute indirect addressing (JMP)

+


+

        #   address  R/W description

+

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

+

        1     PC      R  fetch opcode, increment PC

+

        2     PC      R  fetch pointer address low, increment PC

+

        3     PC      R  fetch pointer address high, increment PC

+

        4   pointer   R  fetch low address to latch

+

        5  pointer+1* R  fetch PCH, copy latch to PCL

+


+

       Note: * The PCH will always be fetched from the same page

+

               than PCL, i.e. page boundary crossing is not handled.

+


+

                How Real Programmers Acknowledge Interrupts

+


+

  With RMW instructions:

+


+

        ; beginning of combined raster/timer interrupt routine

+

        LSR $D019       ; clear VIC interrupts, read raster interrupt flag to C

+

        BCS raster      ; jump if VIC caused an interrupt

+

        ...             ; timer interrupt routine

+


+

        Operational diagram of LSR $D019:

+


+

          #  data  address  R/W

+

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

+

          1   4E     PC      R   fetch opcode

+

          2   19    PC+1     R   fetch address low

+

          3   D0    PC+2     R   fetch address high

+

          4   xx    $D019    R   read memory

+

          5   xx    $D019    W   write the value back, rotate right

+

          6  xx/2   $D019    W   write the new value back

+


+

        The 5th cycle acknowledges the interrupt by writing the same

+

        value back. If only raster interrupts are used, the 6th cycle

+

        has no effect on the VIC. (It might acknowledge also some

+

        other interrupts.)

+


+

  With indexed addressing:

+


+

        ; acknowledge interrupts to both CIAs

+

        LDX #$10

+

        LDA $DCFD,X

+


+

        Operational diagram of LDA $DCFD,X:

+


+

          #  data  address  R/W  description

+

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

+

          1   BD     PC      R   fetch opcode

+

          2   FD    PC+1     R   fetch address low

+

          3   DC    PC+2     R   fetch address high, add X to address low

+

          4   xx    $DC0D    R   read from address, fix high byte of address

+

          5   yy    $DD0D    R   read from right address

+


+

        ; acknowledge interrupts to CIA 2

+

        LDX #$10

+

        STA $DDFD,X

+


+

        Operational diagram of STA $DDFD,X:

+


+

          #  data  address  R/W  description

+

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

+

          1   9D     PC      R   fetch opcode

+

          2   FD    PC+1     R   fetch address low

+

          3   DC    PC+2     R   fetch address high, add X to address low

+

          4   xx    $DD0D    R   read from address, fix high byte of address

+

          5   ac    $DE0D    W   write to right address

+


+

  With branch instructions:

+


+

        ; acknowledge interrupts to CIA 2

+

                LDA #$00  ; clear N flag

+

                JMP $DD0A

+

        DD0A    BPL $DC9D ; branch

+

        DC9D    BRK       ; return

+


+

        You need the following preparations to initialize the CIA registers:

+


+

                LDA #$91  ; argument of BPL

+

                STA $DD0B

+

                LDA #$10  ; BPL

+

                STA $DD0A

+

                STA $DD08 ; load the ToD values from the latches

+

                LDA $DD0B ; freeze the ToD display

+

                LDA #$7F

+

                STA $DC0D ; assure that $DC0D is $00

+


+

        Operational diagram of BPL $DC9D:

+


+

          #  data  address  R/W  description

+

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

+

          1   10    $DD0A    R   fetch opcode

+

          2   91    $DD0B    R   fetch argument

+

          3   xx    $DD0C    R   fetch opcode, add argument to PCL

+

          4   yy    $DD9D    R   fetch opcode, fix PCH

+

        ( 5   00    $DC9D    R   fetch opcode )

+


+

        ; acknowledge interrupts to CIA 1

+

                LSR       ; clear N flag

+

                JMP $DCFA

+

        DCFA    BPL $DD0D

+

        DD0D    BRK

+


+

        ; Again you need to set the ToD registers of CIA 1 and the

+

        ; Interrupt Control Register of CIA 2 first.

+


+

        Operational diagram of BPL $DD0D:

+


+

          #  data  address  R/W  description

+

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

+

          1   10    $DCFA    R   fetch opcode

+

          2   11    $DCFB    R   fetch argument

+

          3   xx    $DCFC    R   fetch opcode, add argument to PCL

+

          4   yy    $DC0D    R   fetch opcode, fix PCH

+

        ( 5   00    $DD0D    R   fetch opcode )

+


+

        ; acknowledge interrupts to CIA 2 automagically

+

                ; preparations

+

                LDA #$7F

+

                STA $DD0D       ; disable all interrupt sources of CIA2

+

                LDA $DD0E

+

                AND #$BE        ; ensure that $DD0C remains constant

+

                STA $DD0E       ; and stop the timer

+

                LDA #$FD

+

                STA $DD0C       ; parameter of BPL

+

                LDA #$10

+

                STA $DD0B       ; BPL

+

                LDA #$40

+

                STA $DD0A       ; RTI/parameter of LSR

+

                LDA #$46

+

                STA $DD09       ; LSR

+

                STA $DD08       ; load the ToD values from the latches

+

                LDA $DD0B       ; freeze the ToD display

+

                LDA #$09

+

                STA $0318

+

                LDA #$DD

+

                STA $0319       ; change NMI vector to $DD09

+

                LDA #$FF        ; Try changing this instruction's operand

+

                STA $DD05       ; (see comment below).

+

                LDA #$FF

+

                STA $DD04       ; set interrupt frequency to 1/65536 cycles

+

                LDA $DD0E

+

                AND #$80

+

                ORA #$11

+

                LDX #$81

+

                STX $DD0D       ; enable timer interrupt

+

                STA $DD0E       ; start timer

+


+

                LDA #$00        ; To see that the interrupts really occur,

+

                STA $D011       ; use something like this and see how

+

        LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

+

                BNE LOOP        ; #$FF to #$0F changes the image.

+


+

        When an NMI occurs, the processor jumps to Kernal code, which jumps to

+

        ($0318), which points to the following routine:

+


+

        DD09    LSR $40         ; clear N flag

+

                BPL $DD0A       ; Note: $DD0A contains RTI.

+


+

        Operational diagram of BPL $DD0A:

+


+

          #  data  address  R/W  description

+

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

+

          1   10    $DD0B    R   fetch opcode

+

          2   11    $DD0C    R   fetch argument

+

          3   xx    $DD0D    R   fetch opcode, add argument to PCL

+

          4   40    $DD0A    R   fetch opcode, (fix PCH)

+


+

  With RTI:

+


+

        ; the fastest possible interrupt handler in the 6500 family

+

                ; preparations

+

                SEI

+

                LDA $01         ; disable ROM and enable I/O

+

                AND #$FD

+

                ORA #$05

+

                STA $01

+

                LDA #$7F

+

                STA $DD0D       ; disable CIA 2's all interrupt sources

+

                LDA $DD0E

+

                AND #$BE        ; ensure that $DD0C remains constant

+

                STA $DD0E       ; and stop the timer

+

                LDA #$40

+

                STA $DD0C       ; store RTI to $DD0C

+

                LDA #$0C

+

                STA $FFFA

+

                LDA #$DD

+

                STA $FFFB       ; change NMI vector to $DD0C

+

                LDA #$FF        ; Try changing this instruction's operand

+

                STA $DD05       ; (see comment below).

+

                LDA #$FF

+

                STA $DD04       ; set interrupt frequency to 1/65536 cycles

+

                LDA $DD0E

+

                AND #$80

+

                ORA #$11

+

                LDX #$81

+

                STX $DD0D       ; enable timer interrupt

+

                STA $DD0E       ; start timer

+


+

                LDA #$00        ; To see that the interrupts really occur,

+

                STA $D011       ; use something like this and see how

+

        LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

+

                BNE LOOP        ; #$FF to #$0F changes the image.

+


+

        When an NMI occurs, the processor jumps to Kernal code, which

+

        jumps to ($0318), which points to the following routine:

+


+

        DD0C    RTI

+


+

        How on earth can this clear the interrupts? Remember, the

+

        processor always fetches two successive bytes for each

+

        instruction.

+


+

        A little more practical version of this is redirecting the NMI

+

        (or IRQ) to your own routine, whose last instruction is JMP

+

        $DD0C or JMP $DC0C.  If you want to confuse more, change the 0

+

        in the address to a hexadecimal digit different from the one

+

        you used when writing the RTI.

+


+

        Or you can combine the latter two methods:

+


+

        DD09    LSR $xx  ; xx is any appropriate BCD value 00-59.

+

                BPL $DCFC

+

        DCFC    RTI

+


+

        This example acknowledges interrupts to both CIAs.

+


+

  If you want to confuse the examiners of your code, you can use any

+

of these techniques. Although these examples use no undefined opcodes,

+

they do not necessarily run correctly on CMOS processors. However, the

+

RTI example should run on 65C02 and 65C816, and the latter branch

+

instruction example might work as well.

+


+

  The RMW instruction method has been used in some demos, others were

+

developed by Marko M"akel"a. His favourite is the automagical RTI

+

method, although it does not have any practical applications, except

+

for some time dependent data decryption routines for very complicated

+

copy protections.

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create iPhone documentation

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/AVICapturing.html b/web/help/AVICapturing.html index 0ca35f81..4e554a28 100644 --- a/web/help/AVICapturing.html +++ b/web/help/AVICapturing.html @@ -1,94 +1,285 @@ - - + + + + + - AVI Capturing - - - - - - - - - - + + + + + + + + AVI Capturing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

AVI Capturing

- -
- General ›› Famicom Disk System ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Video & Audio Capturing

-


-

Introduction

-


-

FCEU allows for outputting Video/Audio into .avi files or capturing audio only into .wav files.  This can be used to capture one's playing or for dumping movie files (.fm2) to .avi files.

-


-


-

Capturing a Movie File (.fm2) to Video/Audio (AVI)

-


-

-Pause the emulator by navigating to NES > Emulation Speed > pause or pressing the pause hotkey (the pause key by default).  

-

-For a faster capture increase emulation speed (you can capture at any emulation speed and FCEUX will still output a 60 (or 50) fps video file).

-

-Select "Replay Movie" from the File > Movie Menu and select the movie file

-

-If you intend to capture beyond the final frame of the movie file, make sure "Pause after Playback" (Config Menu) is not checked.

-

-Select "Record AVI" in the File > AVI/Wav menu.

-

-Select a file location and the video codec you wish to use.

-

-Unpause the emulator.

-

-When capturing is complete, pause the emulator and select "Stop AVI" in the File Menu.

-


-


-

Capture Audio only

-


-

To capture audio only, navigate to File > AVI/Wav > Record WAV.  Pick a filename and destination for FCEUX to begin capturing the audio to a .wav file (raw .pcm).  To stop WAV recording, select File > AVI/Wav > Stop WAV.

-


-

-

Created with the Personal Edition of HelpNDoc: Create HTML Help, DOC, PDF and print manuals from 1 single source

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

AVI Capturing

+ +
+ +

+

Video & Audio Capturing

+


+

Introduction

+


+

FCEU allows for outputting Video/Audio into .avi files or capturing audio only into .wav files.  This can be used to capture one's playing or for dumping movie files (.fm2) to .avi files.

+


+


+

Capturing a Movie File (.fm2) to Video/Audio (AVI)

+


+

-Pause the emulator by navigating to NES > Emulation Speed > pause or pressing the pause hotkey (the pause key by default).  

+

-For a faster capture increase emulation speed (you can capture at any emulation speed and FCEUX will still output a 60 (or 50) fps video file).

+

-Select "Replay Movie" from the File > Movie Menu and select the movie file

+

-If you intend to capture beyond the final frame of the movie file, make sure "Pause after Playback" (Config Menu) is not checked.

+

-Select "Record AVI" in the File > AVI/Wav menu.

+

-Select a file location and the video codec you wish to use.

+

-Unpause the emulator.

+

-When capturing is complete, pause the emulator and select "Stop AVI" in the File Menu.

+


+


+

Capture Audio only

+


+

To capture audio only, navigate to File > AVI/Wav > Record WAV.  Pick a filename and destination for FCEUX to begin capturing the audio to a .wav file (raw .pcm).  To stop WAV recording, select File > AVI/Wav > Stop WAV.

+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured Help generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/AutoFireConfigurations.html b/web/help/AutoFireConfigurations.html index e26140fa..c7a1d28d 100644 --- a/web/help/AutoFireConfigurations.html +++ b/web/help/AutoFireConfigurations.html @@ -1,87 +1,278 @@ - - + + + + + - Auto Fire Settings - - - - - - - - - - + + + + + + + + Auto Fire Settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Auto Fire Settings

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Auto Fire Settings

-


-

Autofire Pattern

-


-

The default configuration for an auto fire key is the alteration of on/off/on/off every frame.  For most games this works nicely, but there are situations where this doesn't work properly.  For example, Double Dragon 2 and Teenage Mutant Ninja Turtles run at 30fps (screen updates every other frame).  To use autofire in these types of games, you would want to set the autofire pattern to 2 on / 2 off.   In a situation where a players weapon on fires every 4th frame, you can set the autofire pattern to 1 on / 3 off.

-


-

Autofire Offset

-


-

The default is for certain frames to have the on setting and others to have the off setting.  For instance, "on" might be lined up with a movie file's even numbers.  But a situation may need the autofire pattern to have "on" on the odd numbers instead.  In this case the autofire offset should be set to 1.  This will delay the normal "on" fire by 1 frame.  If an autofire pattern is set to 2 on / 2 off, an autofire offset of 2 might be necessary.

-


-

Alternate A and B

-


-

Alternate A and B is for a specific case where both the A and B autofire buttons are pressed simultaneously.  With alternate A and B, the fire pattern will be A,B,A,B rather than A+B, off, A+B, off.

-


-


-

Note: All autofire patterns read the Lag Counter (see display) and skip over any frames where input is not polled.  This means that in a laggy area, the autofire pattern will not be affected.

-

-

Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Auto Fire Settings

+ +
+ +

+

Auto Fire Settings

+


+

Autofire Pattern

+


+

The default configuration for an auto fire key is the alteration of on/off/on/off every frame.  For most games this works nicely, but there are situations where this doesn't work properly.  For example, Double Dragon 2 and Teenage Mutant Ninja Turtles run at 30fps (screen updates every other frame).  To use autofire in these types of games, you would want to set the autofire pattern to 2 on / 2 off.   In a situation where a players weapon on fires every 4th frame, you can set the autofire pattern to 1 on / 3 off.

+


+

Autofire Offset

+


+

The default is for certain frames to have the on setting and others to have the off setting.  For instance, "on" might be lined up with a movie file's even numbers.  But a situation may need the autofire pattern to have "on" on the odd numbers instead.  In this case the autofire offset should be set to 1.  This will delay the normal "on" fire by 1 frame.  If an autofire pattern is set to 2 on / 2 off, an autofire offset of 2 might be necessary.

+


+

Alternate A and B

+


+

Alternate A and B is for a specific case where both the A and B autofire buttons are pressed simultaneously.  With alternate A and B, the fire pattern will be A,B,A,B rather than A+B, off, A+B, off.

+


+


+

Note: All autofire patterns read the Lag Counter (see display) and skip over any frames where input is not polled.  This means that in a laggy area, the autofire pattern will not be affected.

+

+

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/CheatSearch.html b/web/help/CheatSearch.html index 58cfdc85..cc8ace04 100644 --- a/web/help/CheatSearch.html +++ b/web/help/CheatSearch.html @@ -1,171 +1,362 @@ - - + + + + + - Cheat Search - - - - - - - - - - + + + + + + + + Cheat Search + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Cheat Search

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

FCE Ultra Cheat Guide

-


-

Introduction

-


-

FCE Ultra allows cheating by the periodic "patching" of arbitrary addresses in the 6502's memory space with arbitrary values, as well as read substitution. "Read substitution" is the method that would be used on a real NES/Famicom, such as done by the Game Genie and Pro Action Replay. It is required to support GG and PAR codes, but since it is relatively slow when done in emulation, it is not the preferred method when a RAM patch will suffice. Also, in FCE Ultra, read substitution will not work properly with zero-page addressing modes(instructions that operate on RAM at $0000 through $00FF).

-


-

The RAM patches are all applied a short time before the emulated vertical blanking period. This detail shouldn't concern most people, though. However, this does mean that cheating with games that use bank-switched RAM may be problematic. Fortunately, such games are not very common (in relation to the total number of NES and Famicom games).

-


-

The cheat search comes with its own set of tools for finding addresses in memory to use for making cheats (or for monitoring the addresses in the memory watch window)

-


-

Cheat Files

-


-

By default cheat files (.cht) are stored in the "cheats" subdirectory under the base FCEUX. The files are in a simple plain-text format. Each line represents a one-byte memory patch. The format is as follows(text in brackets [] represents optional parameters):

-


-

   [S][C][:]Address(hex):Value(hex):[Compare value:]Description

-


-

Example:

-


-

   040e:05:Infinite super power.

-


-

A colon(:) near the beginning of the line is used to disable the cheat. "S" denotes a cheat that is a read-substitute-style cheat(such as with Game Genie cheats), and a "C" denotes that the cheat has a compare value.

-


-

Note:  When a game is loaded, FCEUX will load any accompanying saved .cht file automatically.

-


-

The default .cht file folder can be changed with the Directory Override menu.

-


-

The Cheat Search Menu

-


-

The cheat search interface consists of several components: a list of addresses and associated data for a search, several command buttons, and the search parameters.

-


-

All addresses listed in the cheat search windows are in unsigned 16-bit hexadecimal format and all values in these windows are in an unsigned 8-bit decimal format(the range for values is 0 through 255).

-


-

Active Cheats

-


-

The Active cheats window on the left contains the list of cheats for the currently loaded game. Existing cheats can be selected, edited, and updated using the "Update" button.

-


-

Each entry in the list can be named. If you didn't provide a name, it will be automatically named using this format:

-

For simple "Substitute" type of cheats: * Address:Value

-

For "Compare" type of cheats: * Address?Compare:Value

-


-

The "Address" is the location in the 6502's address space.  The * denotes that the current cheat is active (double clicking will toggle on/off). "Value" is the value (in hex) that is written to the addresses on each update. "Compare" it the value that must be at the address, or else the Value won't be written there. This allows making cheats more safe.

-


-

You can Add, Delete, and Update cheats in the Active Cheats window with the boxes below.

-

You can use "Add from CHT file..." button to load cheats from an existing file (in case the file name does not match the ROM name, so it didn't load automatically). Alternatively, you can drag and drop any .cht file into the FCEUX window.

-


-

There is also a right-click menu with the options Toggle selected Cheats, Poke Cheat Value and Goto in Hex Editor, and Delete selected Cheats.

-


-

Toggle Cheats is like Double Clicking, it enables or disables the cheat code. You can select many cheats in the list and toggle them all at once.

-

Poke Cheat Value is like turning the cheat on, but in this case there's no off switch. If the code is on when you use this, then when the code is turned off, it will revert to the value last used. Good for one time life refills, if you want that sort of thing.

-

Goto in Hex Editor opens the Hex Editor window, and puts the cursor on the address shown. It's somewhat similar to how Bookmarks work in the Hex Editor.

-


-

To create a new cheat, you have to find an address, for this use the cheat search portion of the window.

-


-


-

Cheat Search

-


-

The cheat search is used to find a specific value in the games RAM by process of elimination.

-


-

The possibilities window is in the format of  Address:Original Value:Current Value

-

The address is the location in the 6502's address space, the original value is the value that was stored at this address when the search was reset, and the current value is the value that is currently stored at that address. Selecting an item in this list will automatically cause the "Address" field in the cheat information box on the right side of the window to be updated with the selected address.

-


-

The "Reset" button resets the search process; all valid addresses are displayed in the possibilities window and the data values at those addresses noted in both the left and right columns.  The number of possibilities is displayed at the top.  Resetting will set it to 2048 or 10240 depending on if the game uses "On cartridge ram" ($6000-$7FFF).  (See NES RAM)

-


-

The left column is the "previous value" and the right column is the "current value"

-


-

The "Known Value", "Equal", "Not Equal", Greater than" and Less than" buttons perform a search based on the search parameter and removes any non-matching addresses from the address list.   It then sets the "previous value" column to the contents of the "current value"

-


-

"Known Value" will search for all addresses that match the value in the box to the right (the value is in hex).

-


-

"Equal" will search for all addresses that have the same value now as the last search (or since reset was pressed, if there has not yet been a search).

-


-

"Not equal" will search for all addresses that have changed sine the last search (or since reset was pressed, if there has not yet been a search).

-

If the checkbox next to it is checked it will looks for values that have changed by the value in the number box to the right.  For instance, if it is checked and the number is 5, it will search for all values that are +- 5 from the previous value.

-


-

"Greater than" functions like "Not equal" except it only searches for values that have increased since the last search.

-


-

"Less than" functions like "Not equal" except it only searches for values that have decreased since the last search.

-


-

Using the Results

-


-

Any value in the possibilities list can be sent to memory watch by double clicking it.  

-

Highlighting it and hitting the "Add" button under the Active cheats window will automatically activate it as a cheat with the value set to its current value.

-


-

Example

-


-

Here is an example of cheat search in action.

-


-

Let's say I am playing Mega man 3 and I want to find Mega man's energy level in the game's ram.  I will start by opening the ROM and selecting a level.  At this point, I know Mega man's energy address is active.  So I will pause the game and open the cheat search and hit the reset button.  The game uses SRAM so the possibilities window will say 10240 "possibilities".  

-

Next I will frame advance (or briefly unpause) the game.  At this point I know Mega man's energy level is still the same as it was.  So I click the "equal" button.   Next I want to take damage.  I know for sure now that the energy level has decreased so after the "ouch" animation, I click the "Less than button".  This will cut the possibilities down significantly.  Next I will advance some more and click the "Equal" button since I know the value is still the previous value.  I will repeat this cycle until I am down to 1 or just a few values.  From there I can double click the values to send them to memory watch to monitor them more closely to weed them out.  (Note:  Mega man's energy is located in $00A2).

-


-

Context Menu

-


-

Right-clicking in the active cheats list brings up the context menu.

-


-

Toggle Cheat - does the same thing as double clicking

-


-

Poke cheat value - has a different affect that normal freezing, this makes a one time write of that value as opposed to freezing it temporarily to that value and having it restored later.  It has the same affect as typing in values in the Hex Editor.

-


-

Goto In Hex Editor - Opens the Hex editor dialog to the position of the selected RAM value.

-


-

-

Created with the Personal Edition of HelpNDoc: Easy CHM and documentation editor

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Cheat Search

+ +
+ +

+

FCE Ultra Cheat Guide

+


+

Introduction

+


+

FCE Ultra allows cheating by the periodic "patching" of arbitrary addresses in the 6502's memory space with arbitrary values, as well as read substitution. "Read substitution" is the method that would be used on a real NES/Famicom, such as done by the Game Genie and Pro Action Replay. It is required to support GG and PAR codes, but since it is relatively slow when done in emulation, it is not the preferred method when a RAM patch will suffice. Also, in FCE Ultra, read substitution will not work properly with zero-page addressing modes(instructions that operate on RAM at $0000 through $00FF).

+


+

The RAM patches are all applied a short time before the emulated vertical blanking period. This detail shouldn't concern most people, though. However, this does mean that cheating with games that use bank-switched RAM may be problematic. Fortunately, such games are not very common (in relation to the total number of NES and Famicom games).

+


+

The cheat search comes with its own set of tools for finding addresses in memory to use for making cheats (or for monitoring the addresses in the memory watch window)

+


+

Cheat Files

+


+

By default cheat files (.cht) are stored in the "cheats" subdirectory under the base FCEUX. The files are in a simple plain-text format. Each line represents a one-byte memory patch. The format is as follows(text in brackets [] represents optional parameters):

+


+

    [S][C][:]Address(hex):Value(hex):[Compare value:]Description 

+


+

Example:

+


+

    040e:05:Infinite super power.

+


+

A colon(:) near the beginning of the line is used to disable the cheat. "S" denotes a cheat that is a read-substitute-style cheat(such as with Game Genie cheats), and a "C" denotes that the cheat has a compare value.

+


+

Note:  When a game is loaded, FCEUX will load any accompanying saved .cht file automatically.

+


+

The default .cht file folder can be changed with the Directory Override menu.

+


+

The Cheat Search Menu

+


+

The cheat search interface consists of several components: a list of addresses and associated data for a search, several command buttons, and the search parameters.

+


+

All addresses listed in the cheat search windows are in unsigned 16-bit hexadecimal format and all values in these windows are in an unsigned 8-bit decimal format(the range for values is 0 through 255).

+


+

Active Cheats

+


+

The Active cheats window on the left contains the list of cheats for the currently loaded game. Existing cheats can be selected, edited, and updated using the "Update" button.

+


+

Each entry in the list can be named. If you didn't provide a name, it will be automatically named using this format:

+

For simple "Substitute" type of cheats: * Address:Value

+

For "Compare" type of cheats: * Address?Compare:Value

+


+

The "Address" is the location in the 6502's address space.  The * denotes that the current cheat is active (double clicking will toggle on/off). "Value" is the value (in hex) that is written to the addresses on each update. "Compare" it the value that must be at the address, or else the Value won't be written there. This allows making cheats more safe.

+


+

You can Add, Delete, and Update cheats in the Active Cheats window with the boxes below.

+

You can use "Add from CHT file..." button to load cheats from an existing file (in case the file name does not match the ROM name, so it didn't load automatically). Alternatively, you can drag and drop any .cht file into the FCEUX window.

+


+

There is also a right-click menu with the options Toggle selected Cheats, Poke Cheat Value and Goto in Hex Editor, and Delete selected Cheats.

+


+

Toggle Cheats is like Double Clicking, it enables or disables the cheat code. You can select many cheats in the list and toggle them all at once.

+

Poke Cheat Value is like turning the cheat on, but in this case there's no off switch. If the code is on when you use this, then when the code is turned off, it will revert to the value last used. Good for one time life refills, if you want that sort of thing.

+

Goto in Hex Editor opens the Hex Editor window, and puts the cursor on the address shown. It's somewhat similar to how Bookmarks work in the Hex Editor.

+


+

To create a new cheat, you have to find an address, for this use the cheat search portion of the window.

+


+


+

Cheat Search

+


+

The cheat search is used to find a specific value in the games RAM by process of elimination.

+


+

The possibilities window is in the format of  Address:Original Value:Current Value

+

The address is the location in the 6502's address space, the original value is the value that was stored at this address when the search was reset, and the current value is the value that is currently stored at that address. Selecting an item in this list will automatically cause the "Address" field in the cheat information box on the right side of the window to be updated with the selected address.

+


+

The "Reset" button resets the search process; all valid addresses are displayed in the possibilities window and the data values at those addresses noted in both the left and right columns.  The number of possibilities is displayed at the top.  Resetting will set it to 2048 or 10240 depending on if the game uses "On cartridge ram" ($6000-$7FFF).  (See NES RAM)

+


+

The left column is the "previous value" and the right column is the "current value"

+


+

The "Known Value", "Equal", "Not Equal", Greater than" and Less than" buttons perform a search based on the search parameter and removes any non-matching addresses from the address list.   It then sets the "previous value" column to the contents of the "current value"

+


+

"Known Value" will search for all addresses that match the value in the box to the right (the value is in hex).

+


+

"Equal" will search for all addresses that have the same value now as the last search (or since reset was pressed, if there has not yet been a search).

+


+

"Not equal" will search for all addresses that have changed sine the last search (or since reset was pressed, if there has not yet been a search).

+

If the checkbox next to it is checked it will looks for values that have changed by the value in the number box to the right.  For instance, if it is checked and the number is 5, it will search for all values that are +- 5 from the previous value.

+


+

"Greater than" functions like "Not equal" except it only searches for values that have increased since the last search.

+


+

"Less than" functions like "Not equal" except it only searches for values that have decreased since the last search.

+


+

Using the Results

+


+

Any value in the possibilities list can be sent to memory watch by double clicking it.  

+

Highlighting it and hitting the "Add" button under the Active cheats window will automatically activate it as a cheat with the value set to its current value.

+


+

Example

+


+

Here is an example of cheat search in action.

+


+

Let's say I am playing Mega man 3 and I want to find Mega man's energy level in the game's ram.  I will start by opening the ROM and selecting a level.  At this point, I know Mega man's energy address is active.  So I will pause the game and open the cheat search and hit the reset button.  The game uses SRAM so the possibilities window will say 10240 "possibilities".  

+

Next I will frame advance (or briefly unpause) the game.  At this point I know Mega man's energy level is still the same as it was.  So I click the "equal" button.   Next I want to take damage.  I know for sure now that the energy level has decreased so after the "ouch" animation, I click the "Less than button".  This will cut the possibilities down significantly.  Next I will advance some more and click the "Equal" button since I know the value is still the previous value.  I will repeat this cycle until I am down to 1 or just a few values.  From there I can double click the values to send them to memory watch to monitor them more closely to weed them out.  (Note:  Mega man's energy is located in $00A2).

+


+

Context Menu

+


+

Right-clicking in the active cheats list brings up the context menu.

+


+

Toggle Cheat - does the same thing as double clicking

+


+

Poke cheat value - has a different affect that normal freezing, this makes a one time write of that value as opposed to freezing it temporarily to that value and having it restored later.  It has the same affect as typing in values in the Hex Editor.

+


+

Goto In Hex Editor - Opens the Hex editor dialog to the position of the selected RAM value.

+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/CodeDataLogger.html b/web/help/CodeDataLogger.html index 8af31fff..90b0c287 100644 --- a/web/help/CodeDataLogger.html +++ b/web/help/CodeDataLogger.html @@ -1,198 +1,407 @@ - - + + + + + - Code/Data Logger - - - - - - - - - - + + + + + + + + Code/Data Logger + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Code/Data Logger

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Code/Data Logger

+ +
+

-

Code/Data Logger

-


-


-

Introduction

-


-

The Code/Data Logger makes it much easier to reverse-engineer NES ROMs. The basic idea behind it is that a normal NES disassembler cannot distinguish between code (which is executed) and data (which is read). The Code/Data Logger keeps track of what is executed and what is read while the game is played, and then you can save this information into a .cdl file, which is essentially a mask that tells which bytes in the ROM are code and which are data. The file can be used in conjunction with a suitable disassembler to disassemble only the actual game code, resulting in a much cleaner source code where code and data are properly separated.

-


-

Using the Code/Data Logger

-


-

The Code/Data Logger keeps track of every byte in the ROM and records whether it's code (is executed) or data (is read).

-

You can combine this logging feature with other tools to make them much more powerful:

-
    -
  • combine with Debugger to see which branches of the game code were executed and which weren't yet
  • -
  • combine with Trace Logger to let it log the code selectively
  • -
  • combine with PPU Viewer to let it only display graphics that was drawn on screen at least once
  • -
  • combine with Hex Editor to enable smart coloring of bytes (so you can observe which bytes are used by the game and how/when they are used)
  • -
  • combine with (an external) Tile Viewer to see which graphics was used during certain play session, and which was not
  • -
  • combine with (an external) ROM Corruptor to make it only corrupt data, but not code
  • -
  • combine with (an external) Disassembler to help it separate code from data
  • +

    Code/Data Logger

    +


    +


    +

    Introduction

    +


    +

    The Code/Data Logger makes it much easier to reverse-engineer NES ROMs. The basic idea behind it is that a normal NES disassembler cannot distinguish between code (which is executed) and data (which is read). The Code/Data Logger keeps track of what is executed and what is read while the game is played, and then you can save this information into a .cdl file, which is essentially a mask that tells which bytes in the ROM are code and which are data. The file can be used in conjunction with a suitable disassembler to disassemble only the actual game code, resulting in a much cleaner source code where code and data are properly separated.

    +


    +

    Using the Code/Data Logger

    +


    +

    The Code/Data Logger keeps track of every byte in the ROM and records whether it's code (is executed) or data (is read).

    +

    You can combine this logging feature with other tools to make them much more powerful:

    +
      +
    • combine with Debugger to see which branches of the game code were executed and which weren't yet
    • +
    • combine with Trace Logger to let it log the code selectively
    • +
    • combine with PPU Viewer to let it only display graphics that was drawn on screen at least once
    • +
    • combine with Hex Editor to enable smart coloring of bytes (so you can observe which bytes are used by the game and how/when they are used)
    • +
    • combine with (an external) Tile Viewer to see which graphics was used during certain play session, and which was not
    • +
    • combine with (an external) ROM Corruptor to make it only corrupt data, but not code
    • +
    • combine with (an external) Disassembler to help it separate code from data
    -


    -

    See, it is very useful for finding certain types of data or code branches. It also makes debugging work more visual, since you can always see which lines of the disassembled code were executed and which weren't.

    -


    -

    Furthermore, while the Code/Data Logger is running, the Hex Editor will color-code ROM bytes depending on whether they were logged as code or data:

    -


    -

    For PRG ROM:

    -

    Dark-yellow - the byte is code

    -

    Blue - the byte is data

    -

    Cyan - the byte is PCM audio data

    -

    Green - the byte is both code and data

    -


    -

    For CHR ROM:

    -

    Yellow - the byte was rendered

    -

    Light-blue - the byte was read programmatically

    -

    Light-green - the byte was both rendered and read programmatically

    -


    -

    The Code/Data Logger can also be used to generate a stripped NES ROM.

    -

    "Stripped" NES ROM is a ROM in which everything that was not logged by the Code/Data Logger is removed. It can be useful in many ways, for example, you can view the ROM in an external Hex Editor or a Tile Viewer, and you'll see only the parts that were used while playing. Furthermore, you could use it to create a demo ROM by only playing through the parts you would like others to see.

    -

    Example of such usage:

    -

    1. Open the Code/Data Logger, and press Start to begin logging.

    -

    2. Perform a soft and a hard reset while logging, in order to capture the ROM's startup sequence. If you don't do so, you can distribute a save-state file so they will start from within the game.

    -

    3. If the game has Save-RAM (e.g. Zelda), you will need to capture the game's Save-RAM initialization routines; you can try to do so by deleting the game's *.sav file and then perform a soft and hard reset again while logging.

    -

    4. Play through whatever levels you want present in the demo ROM. Be sure to perform every move, get every item, etc., so that the code and data necessary for those things are logged. If, for example, you fail to perform some special move, and then someone plays the stripped ROM and attempts to perform that move, the game may very well crash or glitch up, because there are zeros in the stripped ROM instead of the code responsible for handling this special move.

    -

    5. Save the stripped NES ROM.

    -


    -

    Alternatively, you can save Unused Data (a ROM which is the opposite to the Stripped ROM). For example, you can play through the game, then save Unused Data ROM and watch it in a Tile Viewer to find unused graphics (possibly stumble upon secrets and easter eggs).

    -


    -

    Note: When you "Load" another .cdl file, it does not clear the current log; instead, it combines ("arithmetical OR") it with the information in the file. This can be useful if you're trying to obtain a complete log of certain game, as multiple people can play through the game and keep own code/data logs, and then the results can be combined into an all-encompassing log. But if you would like to actually clear the code/data log, press the "Reset Log" button.

    -


    -
    -


    -

    CDL files are just a mask of the ROM; that is, they are of the same size as the ROM, and each byte represents the corresponding byte of the ROM. The format of each byte is like so (in binary):

    -


    -

    For PRG ROM:

    -
    - - - - - - - - - - +


    +

    See, it is very useful for finding certain types of data or code branches. It also makes debugging work more visual, since you can always see which lines of the disassembled code were executed and which weren't.

    +


    +

    Furthermore, while the Code/Data Logger is running, the Hex Editor will color-code ROM bytes depending on whether they were logged as code or data:

    +


    +

    For PRG ROM:

    +

    Dark-yellow - the byte is code

    +

    Blue - the byte is data

    +

    Cyan - the byte is PCM audio data

    +

    Green - the byte is both code and data

    +


    +

    For CHR ROM:

    +

    Yellow - the byte was rendered

    +

    Light-blue - the byte was read programmatically

    +

    Light-green - the byte was both rendered and read programmatically

    +


    +

    The Code/Data Logger can also be used to generate a stripped NES ROM.

    +

    "Stripped" NES ROM is a ROM in which everything that was not logged by the Code/Data Logger is removed. It can be useful in many ways, for example, you can view the ROM in an external Hex Editor or a Tile Viewer, and you'll see only the parts that were used while playing. Furthermore, you could use it to create a demo ROM by only playing through the parts you would like others to see.

    +

    Example of such usage:

    +

    1. Open the Code/Data Logger, and press Start to begin logging.

    +

    2. Perform a soft and a hard reset while logging, in order to capture the ROM's startup sequence. If you don't do so, you can distribute a save-state file so they will start from within the game.

    +

    3. If the game has Save-RAM (e.g. Zelda), you will need to capture the game's Save-RAM initialization routines; you can try to do so by deleting the game's *.sav file and then perform a soft and hard reset again while logging.

    +

    4. Play through whatever levels you want present in the demo ROM. Be sure to perform every move, get every item, etc., so that the code and data necessary for those things are logged. If, for example, you fail to perform some special move, and then someone plays the stripped ROM and attempts to perform that move, the game may very well crash or glitch up, because there are zeros in the stripped ROM instead of the code responsible for handling this special move.

    +

    5. Save the stripped NES ROM.

    +


    +

    Alternatively, you can save Unused Data (a ROM which is the opposite to the Stripped ROM). For example, you can play through the game, then save Unused Data ROM and watch it in a Tile Viewer to find unused graphics (possibly stumble upon secrets and easter eggs).

    +


    +

    Note: When you "Load" another .cdl file, it does not clear the current log; instead, it combines ("arithmetical OR") it with the information in the file. This can be useful if you're trying to obtain a complete log of certain game, as multiple people can play through the game and keep own code/data logs, and then the results can be combined into an all-encompassing log. But if you would like to actually clear the code/data log, press the "Reset Log" button.

    +


    +
    +


    +

    CDL files are just a mask of the ROM; that is, they are of the same size as the ROM, and each byte represents the corresponding byte of the ROM. The format of each byte is like so (in binary):

    +


    +

    For PRG ROM:

    +
    +

    x

    -

    P

    -

    d

    -

    c

    -

    A

    -

    A

    -

    D

    -

    C

    -
    + + + + + + + + + +
    +

    x

    +
    +

    P

    +
    +

    d

    +
    +

    c

    +
    +

    A

    +
    +

    A

    +
    +

    D

    +
    +

    C

    +
    -

                   

    -

           C = Whether it was accessed as code.

    -

           D = Whether it was accessed as data.

    -

           AA = Into which ROM bank it was mapped when last accessed:

    -

                   00 = $8000-$9FFF        01 = $A000-$BFFF

    -

                   10 = $C000-$DFFF        11 = $E000-$FFFF

    -

           c = Whether indirectly accessed as code.

    -

                   (e.g. as the destination of a JMP ($nnnn) instruction)

    -

           d = Whether indirectly accessed as data.

    -

                   (e.g. as the destination of an LDA ($nn),Y instruction)

    -

           P = If logged as PCM audio data.

    -

           x = unused.

    -


    -

    For CHR ROM:

    -
    - - - - - - - - - - +

                   

    +

           C = Whether it was accessed as code.

    +

           D = Whether it was accessed as data.

    +

           AA = Into which ROM bank it was mapped when last accessed:

    +

                   00 = $8000-$9FFF        01 = $A000-$BFFF

    +

                   10 = $C000-$DFFF        11 = $E000-$FFFF

    +

           c = Whether indirectly accessed as code.

    +

                   (e.g. as the destination of a JMP ($nnnn) instruction)

    +

           d = Whether indirectly accessed as data.

    +

                   (e.g. as the destination of an LDA ($nn),Y instruction)

    +

           P = If logged as PCM audio data.

    +

           x = unused.

    +


    +

    For CHR ROM:

    +
    +

    x

    -

    x

    -

    x

    -

    x

    -

    x

    -

    x

    -

    R

    -

    D

    -
    + + + + + + + + + +
    +

    x

    +
    +

    x

    +
    +

    x

    +
    +

    x

    +
    +

    x

    +
    +

    x

    +
    +

    R

    +
    +

    D

    +
    -

                   

    -

           D = Whether it was drawn on screen (rendered by PPU at runtime)

    -

           R = Whether it was read programmatically using port $2007

    -

                   (e.g. Argus_(J).nes checks if the bankswitching works by reading the same byte of CHR data before and after switching)

    -

           x = unused.

    -


    -
    -


    -


    -

    CDL files make possible a number of things never done before. First, a PCM data ripper could be created that scans for data that has the 'P' bit set, in order to find/rip/play every PCM sample in a ROM. Also, it is possible for someone to make a more intelligent ROM corruptor that only corrupts data (by checking the 'D' bit). In any case, the Code/Data Logger opens many new possibilities for discovering useful things in games. Another interesting possibility would be to use the Code/Data Logger on an NSF file to create a stripped NSF. Such an NSF would contain nothing but the relevant subroutines and data required by each tune played; this would be helpful to NSF rippers by removing irrelevant information. Thus, an NSF ripper could create a stripped NSF by listening to each track while the Code/Data Logger operates on it, and then saving the stripped NSF. It should be noted that this capability, though tested and working on private builds, is detrimental to the process of fixing broken NSF files. For this reason, data logging is allowed for NSF files, but stripping NSF files of unused data is disabled.

    -


    -

    The Code/Data Logger becomes the most useful when you need to restore a full source code of a game using e.g. IDA or another disassembler. There you can write a custom IDC script that uses a CDL file and calls MakeCode()/MakeData() functions to help the disassembler distinguish code from data. Making full and working/reassemblable disassembly becomes really easy this way.

    -


    -


    -


    -


    -


    +

                   

    +

           D = Whether it was drawn on screen (rendered by PPU at runtime)

    +

           R = Whether it was read programmatically using port $2007

    +

                   (e.g. Argus_(J).nes checks if the bankswitching works by reading the same byte of CHR data before and after switching)

    +

           x = unused.

    +


    +
    +


    +


    +

    CDL files make possible a number of things never done before. First, a PCM data ripper could be created that scans for data that has the 'P' bit set, in order to find/rip/play every PCM sample in a ROM. Also, it is possible for someone to make a more intelligent ROM corruptor that only corrupts data (by checking the 'D' bit). In any case, the Code/Data Logger opens many new possibilities for discovering useful things in games. Another interesting possibility would be to use the Code/Data Logger on an NSF file to create a stripped NSF. Such an NSF would contain nothing but the relevant subroutines and data required by each tune played; this would be helpful to NSF rippers by removing irrelevant information. Thus, an NSF ripper could create a stripped NSF by listening to each track while the Code/Data Logger operates on it, and then saving the stripped NSF. It should be noted that this capability, though tested and working on private builds, is detrimental to the process of fixing broken NSF files. For this reason, data logging is allowed for NSF files, but stripping NSF files of unused data is disabled.

    +


    +

    The Code/Data Logger becomes the most useful when you need to restore a full source code of a game using e.g. IDA or another disassembler. There you can write a custom IDC script that uses a CDL file and calls MakeCode()/MakeData() functions to help the disassembler distinguish code from data. Making full and working/reassemblable disassembly becomes really easy this way.

    +


    +


    +


    +


    +


    -

    Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

    -
- - + + +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + - -
- - diff --git a/web/help/CommandLineOptions.html b/web/help/CommandLineOptions.html index 8f983b56..a4ffd72b 100644 --- a/web/help/CommandLineOptions.html +++ b/web/help/CommandLineOptions.html @@ -1,250 +1,441 @@ - - + + + + + - Command Line Options - - - - - - - - - - + + + + + + + + Command Line Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Command Line Options

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Command Line Options

-


-


-

FCEUX offers numerous command line options.

-

All commands are case sensitive.

-


-

ROM name

-

Plays specified ROM (ROM name must always be put last in command line arguments)

-


-

fceux path\rom.nes (or rom.zip)

-


-

       fceux smb.nes

-

       fceux c:\fceux\roms\smb.zip

-


-


-

Play Movie File

-

Plays a specified movie (.fm2) file.  A valid ROM must be specified or movie will not be played.

-


-

fcuex -playmovie path\movie.fm2 romname

-


-

       fceux -playmovie smb.fm2 smb.nes

-


-


-

Read-only Status

-

Specifies whether a movie will be in "read-only" or "read & write" mode.  (Note: a specified movie is not required to be used in conjunction with this command). 1 specifies read only status, 0 specifies read & write.

-


-

fceux -readonly flag

-


-

       fceux -readonly 1

-

       fceux -readonly 0 -playmovie smb.fm2 smb.nes

-

       fceux -readonly 1 -playmovie c:\fceux\movies\smb.fm2 c:\fceux\roms\smb.nes

-


-


-

Stop Movie at frame x

-

Specifies that the movie will automatically stop at the specified frame.  (A movie must be specified with -playmovie for this command to work)

-


-

fceux -playmovie path\movie.fm2 -stopframe framenumber romname

-


-

       fceux -playmovie smb.fm2 -stopframe 10000 smb.nes

-


-


-

Load State

-

Specifies FCEUX to automatically load a specified savestate file.  (Must have a specified ROM for this to work).

-


-

fceux -loadstate path\savestatefile romname

-


-

       fceux -loadstate smb0.fc0 smb.nes

-

       fceux -playmovie smb.fm2 -readonly 0 -loadstate smb0.fc0 smb.nes

-


-


-

Pause Movie After Playback

-

Sets the "Pause Movie After Playback" switch on/off.  1 sets it to enabled, 0 sets it to disabled.

-


-

fceux -stopmovie flag

-


-

       fceux -stopmovie 1

-

       fceux -playmovie smb.fm2 -readonly 0 - stopmovie 1 smb0.nes

-


-


-

Frame Display Toggle

-

Toggles whether or not the frame count will be displayed.  1 sets it to on, 0 sets it to off.

-


-

fceux -framedisplay flag

-


-

       fceux -framedisplay 1

-

       fceux -playmovie smb2.fm2 -framedisplay 1 smb0.nes

-


-


-

Input Display Toggle

-

Toggles whether the movie input will be displayed.  1 sets it to on, 0 sets it to off.

-


-

fceux -inputdisplay flag

-


-

       fceux -inputdisplay 1

-

       fceux -playmovie smb2.fm2 -inputdisplay 1 smb0.nes

-


-


-

Allow L+R/U+D

-

Sets whether or not the game will allow L+R/U+D input (see Input config).  1 enables L+R, 0 disables it.

-


-

fceux -allowUDLR flag

-


-

       fceux -allowUDLR 1

-

       fceux -allowUDLR 0 smb0.nes

-


-


-

Enable Background Input

-

Sets the "Enable Background Input" switch on/off.  1 sets it to enabled, 0 sets it to disabled.

-


-

fceux -bginput flag

-


-

       fceux -bginput 0

-

       fceux -playmovie smb.fm2 -readonly 0 -bginput 1 smb0.nes

-


-


-

Use Game Genie

-

Sets the Game Genie Flag (see Toggle Switches).  1 sets it to enabled, 0 sets it to disabled.

-


-

fceux -gg flag

-


-

       fceux -gg 1

-

       fceux -gg 1 smb0.nes

-


-

PAL Emulation

-

Sets the PAL region. 1 sets it to enabled, 0 sets it to disabled.

-

(note: FCEUX will assign PAL emulation automatically if a PAL ROM is loaded)

-


-

fceux -pal flag

-


-

       fceux -pal 1

-

       fceux -pal 1 smb0.nes

-


-

Dendy Emulation

-

Sets the Dendy region. 1 sets it to enabled, 0 sets it to disabled.

-

(note: If set to 1, it will override -pal argument)

-


-

fceux -dendy flag

-


-

       fceux -dendy 1

-

       fceux -dendy 1 smb0.nes

-


-

Movie Status Icon Toggle

-

Sets the Status Icon Toggle (see Toggle Switches).  1 turns off the status icon, 0 turns it on.

-


-

fceux -noicon flag

-


-

       fceux -noicon 1

-

       fceux -noicon 0 smb0.nes

-


-


-

Clip Left and Right Sides

-

Sets the Clip Left and Right Sides Toggle (see Video Config).  1 turns on clipping, 0 turns it off.

-


-

fceux -clipsides flag

-


-

       fceux -clipsides 0 smb0.nes

-


-


-

Allow More than 8 Sprites per Scanline

-

Sets the 8 Sprites per scanline flag (see Video Config).  1 turns on extra sprites, 0 turns it off.

-


-

fceux -no8lim flag

-


-

       fceux -no8lim 0 smb0.nes

-


-


-

Disable Speed Throttling

-

Sets the Disable Speed Throttling When Sound is Disabled flag (see Timing Config).  1 disables throttling, 0 leaves it on.

-


-

fceux -nothrottle flag

-


-

       fceux -nothrottle 0 smb0.nes

-


-


-

Turbo Toggle

-

Sets the Turbo Toggle.  1 Sets Turbo on, 0 leaves it off.

-


-

fceux  -turbo flag

-


-

       fceux -turbo 1 smb0.nes

-


-


-

Load Config File

-

Loads a specified config file rather than the default fceux.cfg

-


-

Warning:  the config file must be in the base directory.  A pathname can NOT be specified in the filename

-


-

fceux -cfg filename

-


-

       fceux -cfg fceux-smbconfig.cfg smb.nes

-


-


-

Load Lua Script

-

Loads a Lua script on startup.

-


-

fceux -lua filename

-


-

       fceux -lua memwatch.lua

-


-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Command Line Options

+ +
+ +

+

Command Line Options

+


+


+

FCEUX offers numerous command line options.

+

All commands are case sensitive.

+


+

ROM name

+

Plays specified ROM (ROM name must always be put last in command line arguments)

+


+

fceux path\rom.nes (or rom.zip)

+


+

       fceux smb.nes

+

       fceux c:\fceux\roms\smb.zip

+


+


+

Play Movie File

+

Plays a specified movie (.fm2) file.  A valid ROM must be specified or movie will not be played.

+


+

fcuex -playmovie path\movie.fm2 romname

+


+

       fceux -playmovie smb.fm2 smb.nes

+


+


+

Read-only Status

+

Specifies whether a movie will be in "read-only" or "read & write" mode.  (Note: a specified movie is not required to be used in conjunction with this command). 1 specifies read only status, 0 specifies read & write.

+


+

fceux -readonly flag

+


+

       fceux -readonly 1

+

       fceux -readonly 0 -playmovie smb.fm2 smb.nes

+

       fceux -readonly 1 -playmovie c:\fceux\movies\smb.fm2 c:\fceux\roms\smb.nes

+


+


+

Stop Movie at frame x

+

Specifies that the movie will automatically stop at the specified frame.  (A movie must be specified with -playmovie for this command to work)

+


+

fceux -playmovie path\movie.fm2 -stopframe framenumber romname

+


+

       fceux -playmovie smb.fm2 -stopframe 10000 smb.nes

+


+


+

Load State

+

Specifies FCEUX to automatically load a specified savestate file.  (Must have a specified ROM for this to work).

+


+

fceux -loadstate path\savestatefile romname

+


+

       fceux -loadstate smb0.fc0 smb.nes

+

       fceux -playmovie smb.fm2 -readonly 0 -loadstate smb0.fc0 smb.nes

+


+


+

Pause Movie After Playback

+

Sets the "Pause Movie After Playback" switch on/off.  1 sets it to enabled, 0 sets it to disabled.

+


+

fceux -stopmovie flag

+


+

       fceux -stopmovie 1

+

       fceux -playmovie smb.fm2 -readonly 0 - stopmovie 1 smb0.nes

+


+


+

Frame Display Toggle

+

Toggles whether or not the frame count will be displayed.  1 sets it to on, 0 sets it to off.

+


+

fceux -framedisplay flag

+


+

       fceux -framedisplay 1

+

       fceux -playmovie smb2.fm2 -framedisplay 1 smb0.nes

+


+


+

Input Display Toggle

+

Toggles whether the movie input will be displayed.  1 sets it to on, 0 sets it to off.

+


+

fceux -inputdisplay flag

+


+

       fceux -inputdisplay 1

+

       fceux -playmovie smb2.fm2 -inputdisplay 1 smb0.nes

+


+


+

Allow L+R/U+D

+

Sets whether or not the game will allow L+R/U+D input (see Input config).  1 enables L+R, 0 disables it.

+


+

fceux -allowUDLR flag

+


+

       fceux -allowUDLR 1

+

       fceux -allowUDLR 0 smb0.nes

+


+


+

Enable Background Input

+

Sets the "Enable Background Input" switch on/off.  1 sets it to enabled, 0 sets it to disabled.

+


+

fceux -bginput flag

+


+

       fceux -bginput 0

+

       fceux -playmovie smb.fm2 -readonly 0 -bginput 1 smb0.nes

+


+


+

Use Game Genie

+

Sets the Game Genie Flag (see Toggle Switches).  1 sets it to enabled, 0 sets it to disabled.

+


+

fceux -gg flag

+


+

       fceux -gg 1

+

       fceux -gg 1 smb0.nes

+


+

PAL Emulation

+

Sets the PAL region. 1 sets it to enabled, 0 sets it to disabled.

+

(note: FCEUX will assign PAL emulation automatically if a PAL ROM is loaded) 

+


+

fceux -pal flag

+


+

       fceux -pal 1

+

       fceux -pal 1 smb0.nes

+


+

Dendy Emulation

+

Sets the Dendy region. 1 sets it to enabled, 0 sets it to disabled.

+

(note: If set to 1, it will override -pal argument) 

+


+

fceux -dendy flag

+


+

       fceux -dendy 1

+

       fceux -dendy 1 smb0.nes

+


+

Movie Status Icon Toggle

+

Sets the Status Icon Toggle (see Toggle Switches).  1 turns off the status icon, 0 turns it on.

+


+

fceux -noicon flag

+


+

       fceux -noicon 1

+

       fceux -noicon 0 smb0.nes

+


+


+

Clip Left and Right Sides

+

Sets the Clip Left and Right Sides Toggle (see Video Config).  1 turns on clipping, 0 turns it off.

+


+

fceux -clipsides flag

+


+

       fceux -clipsides 0 smb0.nes

+


+


+

Allow More than 8 Sprites per Scanline

+

Sets the 8 Sprites per scanline flag (see Video Config).  1 turns on extra sprites, 0 turns it off.

+


+

fceux -no8lim flag

+


+

       fceux -no8lim 0 smb0.nes

+


+


+

Disable Speed Throttling

+

Sets the Disable Speed Throttling When Sound is Disabled flag (see Timing Config).  1 disables throttling, 0 leaves it on.

+


+

fceux -nothrottle flag

+


+

       fceux -nothrottle 0 smb0.nes

+


+


+

Turbo Toggle

+

Sets the Turbo Toggle.  1 Sets Turbo on, 0 leaves it off.

+


+

fceux  -turbo flag

+


+

       fceux -turbo 1 smb0.nes

+


+


+

Load Config File

+

Loads a specified config file rather than the default fceux.cfg

+


+

Warning:  the config file must be in the base directory.  A pathname can NOT be specified in the filename

+


+

fceux -cfg filename

+


+

       fceux -cfg fceux-smbconfig.cfg smb.nes

+


+


+

Load Lua Script

+

Loads a Lua script on startup.

+


+

fceux -lua filename

+


+

       fceux -lua memwatch.lua

+


+

+

Created with the Personal Edition of HelpNDoc: Easy EBook and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Commands.html b/web/help/Commands.html index 164774cc..aa3bc325 100644 --- a/web/help/Commands.html +++ b/web/help/Commands.html @@ -1,264 +1,455 @@ - - + + + + + - Using Lua - - - - - - - - - - + + + + + + + + Using Lua + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Using Lua

- -
- Lua Scripting ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

(written by qFox)

-


-

Introduction

-


-

Lua is a scripting language. It is used in games like Farcry and World of Warcraft (and many other games and applications!). Even though you can find all kinds of tutorials online, let me help you with the basics.

-


-

I will assume you are at least somewhat familiar with the basics of programming. So basic stuff like arrays, variables, strings, loops and if-then-else and branching are not explained here.

-


-

A hello world EmuLua program looks like this:

-


-

while (true) do

-

       gui.text(50,50,"Hello world!");

-

       emu.frameadvance();

-

end;

-


-

When you load the script, the emulator will sort of go into pause mode and hand controls over to Lua (you!). Hence you are responsible for frameadvancing the emulator.

-

IF YOU DO NOT CALL emu.frameadvance AT THE CYCLE OF THE MAIN LOOP YOU WILL FREEZE THE EMULATOR! There. You have been warned. Don't worry though, you'll make this mistake at least once. Just force-quit the application and try again :)

-


-

Syntax

-


-

Now then. Just like any other language, Lua has a few quirks you should be aware of.

-


-

First of all, if's require a then and end. After a couple of days intensive Lua coding, I still make this mistake myself, but the Lua interpreter will prompt you of such errors on load, so don't worry too much about it. So:

-


-

if (something) then

-

       dostuff

-

end;

-


-

Lua uses nil instead of null.

-


-

There are only two values that evaluate to "false", these are "nil" and "false". ANYTHING else will evaluate to true, even 0 or the empty string.

-


-

Comments are denoted by two consecutive dashes; --. Anything after it on the same line is a comment and ignored by Lua. There is no /* */ type of commenting in Lua.

-


-

Variables have a local and global scope. You explicitly make a variable local by declaring it with the "local" keyword.

-


-

somethingglobal; -- accessible by any function or flow

-

local something; -- only known to the same or deeper scope as where it was declared

-


-

Note that variables declared in for loops (see below) are always considered local.

-


-

Arrays are called tables in Lua. To be more precise, Lua uses associative arrays.

-


-

Do not rely on the table.length() when your table can contain nil values, this function stops when it encounters a nil value, thus possibly cutting your table short.

-


-

One experienced programmers will have to get used to is the table offset; tables start at index 1, not 0. That's just the way it is, deal with it.

-


-

There are a few ways to create a table:

-


-

local tbl1 = {}; -- empty table

-

local tbl2 = {"a","b","c","d"}; -- table with 5 strings

-

local tbl3 = {a=1,b=2,c=3}; -- associative table with 3 numbers

-

local tbl4 = {"a",b=2,c="x","d"=5}; -- associative table with mixed content

-


-

Note that you can mix up the data in one table, as shown by tbl4.

-


-

You can refer to table values in a few equivalent manners, using the examples above:

-


-

tbl1[1] -- = nil because tbl1 is empty

-

tbl2[2] -- = "b"

-

tbl3["a"] -- = 1

-

tbl4.b -- = 2

-

tbl2.3 -- = "c"

-


-

When the argument of a function is just a table, the parantheses "()" are optional. So for instance:

-


-

processTable({a=2,b=3});

-


-

Is equivalent to

-


-

processTable{a=2,b=3};

-


-

Another notation that's equivalent is

-


-

filehandle.read(filehandle, 5);

-

filehandle:read(5);

-


-

When using the colon notation ":" Lua will call the function adding the self-reference to the front of the parameterstack.

-


-

Functions behave like objects and are declared in the follow manner:

-


-

function doSomething(somevalue, anothervalue)

-

       dostuffhere

-

end;

-


-

So no curly braces "{}" !

-


-

Some flow control:

-


-

for i=0,15 do

-

 -- do stuff here, i runs from 0 to 15 (inclusive!)

-

end;

-


-

for key,value in pairs(table) do

-

 -- do stuff here. pairs will iterate through the table, splitting the keys and values

-

end;

-


-

while (somethingistrue) do

-


-

end;

-


-

if (somethingistrue) then

-


-

end;

-


-

if (somethingistrue) then

-


-

else

-


-

end;

-


-

if (somethingistrue) then

-


-

elseif (somethingelseistrue) then

-


-

end;

-


-

For comparison, you only have to remember that the exclamationmark is not used. Not equal "!=" is written like tilde-equals "~=" and if (!something) then ... is written with "not " in front of it; if (not something) then...

-


-

For easy reference to the standard libraries look on the bottom half of this page: http://www.lua.org/manual/5.1/

-


-

Lua in FCEUX

-


-

Now then, let's get to the emulator specifics!

-


-

To load a Lua script in FCEU first load a rom (Lua can only do things after each frame cycle so load a rom first). Go to file, at the bottom choose Run Lua Script and select and load the file.

-


-

When Lua starts, the emulator pauses and hands control over to Lua. Lua (that's you!) decides when the next frame is processed. That's why it's very common to write an endless while loop, exiting the main loop of a script will exit the script and hand control back to the emulator. This also happens when a script unexpectingly crashes.

-


-

A bare script looks like this:

-


-

while (true) do

-

 emu.frameadvance();

-

end;

-


-

And is about equal to not running Lua at all. The frameadvance function is the same called internally, so no loss of speed there!

-


-

Bitwise operators:

-


-

Lua does not have bitwise operators, so we supply some for you. These are common bitwise operators, nothing fancy.

-


-

AND(a,b);

-

OR(a,b);

-

XOR(a,b);

-

BIT(n); -- returns a number with only bit n set (1)

-


-

The emulator specific Lua is equal to the one of snes9x, with some platform specific changes (few buttons, for instance).

-

You can find the reference here: http://dehacked.2y.net/snes9x-lua.html

-

The following is a quick reference, you can go to the snes9x reference for more details.

-


-

To paint stuff on screen, use the gui table. This contains a few predefined functions to manipulate the main window. For any coordinate, 0,0 is the top-left pixel of the window. You have to prevent out-of-bound errors yourself for now. If a color can be passed on, it is a string. HTML-syntax is supported ("#34053D"), as well as a FEW colors ("red", "green", "blue" ...).

-


-

gui.text(x, y, str); -- Print a line to the window, you can use \n for a return but it will only work once

-

gui.pixel(x, y, color); -- plot a pixel at the given coordinate

-

gui.line(x1, y1, x2, y2, color); -- plot a line from x1,y1 to x2,y2

-

gui.box(x1, y1, x2, y2, color); -- draw a square from x1,y1 to x2,y2

-

gui.popup(str); -- pops up a messagebox informing the user of something. Real handy when debugging!

-

gui.getpixel(x,y); -- return the values of the pixel at given position. Returns three numbers of the emulator image before paiting is applied.

-

gui.gdscreenshot(); -- Takes a screen shot of the image and returns it in the form of a string which can be imported by the gd library using the gd.createFromGdStr() function

-

(for more gd functions see DeHackED's reference: http://dehacked.2y.net/snes9x-lua.html)

-


-

PAINTING IS ALWAYS ONE FRAME BEHIND! This is because the painting is done at the creation of the next frame, not while Lua is running.

-


-

Emulator control:

-


-

emu.frameadvance(); -- advances emulation ONE frame

-

emu.pause(); -- same as pressing the pause button

-

emu.speedmode(strMode); -- Supported are "normal","turbo","nothrottle","maximum". But know that except for "normal", all other modes will run as "turbo" for now.

-

emu.wait(); -- skips the emulation of the next frame, in case your script needs to wait for something

-


-

Memory control:

-


-

memory.readbyte(adr); -- read one byte from given address and return it. Besides decimal values Lua also allows the hex notation 0x00FA. In FCEUX reading is done BEFORE the cheats are applied!

-

memory.writebyte(adr, value); -- write one byte to the RAM of the NES. writing is done AFTER the hexeditor receives its values, so if you are freezing an address by Lua, it will not show in the hex editor (but it will in the game :)

-

memory.readbytesigned(adr); -- same as readbyte, except this returns a signed value, rather then an unsigned value.

-

memory.register(adr, function); -- binds a function to an address. The function will be called when an address changes. NOTE THAT THIS IS EXPENSIVE (eg.: slow)! Only one function allowed per address.

-


-

Input control:

-


-

You can read and write input by using the joypad table. A input table has the following (case sensitive) keys, where nil denotes they are not to be pressed: up down left right start select A B

-


-

joypad.read(playern); -- get the input table for the player who's input you want to read (a number!)

-

joypad.write(playern, inputtable); -- set the input for player n. Note that this will overwrite any input from the user, and only when this is used.

-


-

Savestates:

-


-

You can load and save to the predefined savestates 1 ... 9 or create new "anonymous" savestates. You must first create a savestate object, which is your handle to a savestate. Then you can pass this handle on to savestate.load or save to do so.

-


-

savestate.create(n); -- n is optional. When supplied, it will create a savestate for slot n, otherwise a new (anonymous) savestate object is created. Note that this does not yet save or load anything!

-

savestate.load(state); -- load the given savestate

-

savestate.save(state); -- save the given savestate

-


-

For an up-to-date list of functions, see the Lua Functions List.

-

-

Created with the Personal Edition of HelpNDoc: Easily create Web Help sites

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Using Lua

+ +
+ +

+

(written by qFox)

+


+

Introduction

+


+

Lua is a scripting language. It is used in games like Farcry and World of Warcraft (and many other games and applications!). Even though you can find all kinds of tutorials online, let me help you with the basics.

+


+

I will assume you are at least somewhat familiar with the basics of programming. So basic stuff like arrays, variables, strings, loops and if-then-else and branching are not explained here.

+


+

A hello world EmuLua program looks like this:

+


+

while (true) do

+

       gui.text(50,50,"Hello world!");

+

       emu.frameadvance();

+

end;

+


+

When you load the script, the emulator will sort of go into pause mode and hand controls over to Lua (you!). Hence you are responsible for frameadvancing the emulator.

+

IF YOU DO NOT CALL emu.frameadvance AT THE CYCLE OF THE MAIN LOOP YOU WILL FREEZE THE EMULATOR! There. You have been warned. Don't worry though, you'll make this mistake at least once. Just force-quit the application and try again :)

+


+

Syntax

+


+

Now then. Just like any other language, Lua has a few quirks you should be aware of.

+


+

First of all, if's require a then and end. After a couple of days intensive Lua coding, I still make this mistake myself, but the Lua interpreter will prompt you of such errors on load, so don't worry too much about it. So:

+


+

if (something) then

+

       dostuff

+

end;

+


+

Lua uses nil instead of null.

+


+

There are only two values that evaluate to "false", these are "nil" and "false". ANYTHING else will evaluate to true, even 0 or the empty string.

+


+

Comments are denoted by two consecutive dashes; --. Anything after it on the same line is a comment and ignored by Lua. There is no /* */ type of commenting in Lua.

+


+

Variables have a local and global scope. You explicitly make a variable local by declaring it with the "local" keyword.

+


+

somethingglobal; -- accessible by any function or flow

+

local something; -- only known to the same or deeper scope as where it was declared

+


+

Note that variables declared in for loops (see below) are always considered local.

+


+

Arrays are called tables in Lua. To be more precise, Lua uses associative arrays.

+


+

Do not rely on the table.length() when your table can contain nil values, this function stops when it encounters a nil value, thus possibly cutting your table short.

+


+

One experienced programmers will have to get used to is the table offset; tables start at index 1, not 0. That's just the way it is, deal with it.

+


+

There are a few ways to create a table:

+


+

local tbl1 = {}; -- empty table

+

local tbl2 = {"a","b","c","d"}; -- table with 5 strings

+

local tbl3 = {a=1,b=2,c=3}; -- associative table with 3 numbers

+

local tbl4 = {"a",b=2,c="x","d"=5}; -- associative table with mixed content

+


+

Note that you can mix up the data in one table, as shown by tbl4.

+


+

You can refer to table values in a few equivalent manners, using the examples above:

+


+

tbl1[1] -- = nil because tbl1 is empty

+

tbl2[2] -- = "b"

+

tbl3["a"] -- = 1

+

tbl4.b -- = 2

+

tbl2.3 -- = "c"

+


+

When the argument of a function is just a table, the parantheses "()" are optional. So for instance:

+


+

processTable({a=2,b=3});

+


+

Is equivalent to

+


+

processTable{a=2,b=3};

+


+

Another notation that's equivalent is

+


+

filehandle.read(filehandle, 5);

+

filehandle:read(5);

+


+

When using the colon notation ":" Lua will call the function adding the self-reference to the front of the parameterstack.

+


+

Functions behave like objects and are declared in the follow manner:

+


+

function doSomething(somevalue, anothervalue)

+

       dostuffhere

+

end;

+


+

So no curly braces "{}" !

+


+

Some flow control:

+


+

for i=0,15 do

+

  -- do stuff here, i runs from 0 to 15 (inclusive!)

+

end;

+


+

for key,value in pairs(table) do

+

  -- do stuff here. pairs will iterate through the table, splitting the keys and values

+

end;

+


+

while (somethingistrue) do

+


+

end;

+


+

if (somethingistrue) then

+


+

end;

+


+

if (somethingistrue) then

+


+

else

+


+

end;

+


+

if (somethingistrue) then

+


+

elseif (somethingelseistrue) then

+


+

end;

+


+

For comparison, you only have to remember that the exclamationmark is not used. Not equal "!=" is written like tilde-equals "~=" and if (!something) then ... is written with "not " in front of it; if (not something) then...

+


+

For easy reference to the standard libraries look on the bottom half of this page: http://www.lua.org/manual/5.1/

+


+

Lua in FCEUX

+


+

Now then, let's get to the emulator specifics!

+


+

To load a Lua script in FCEU first load a rom (Lua can only do things after each frame cycle so load a rom first). Go to file, at the bottom choose Run Lua Script and select and load the file.

+


+

When Lua starts, the emulator pauses and hands control over to Lua. Lua (that's you!) decides when the next frame is processed. That's why it's very common to write an endless while loop, exiting the main loop of a script will exit the script and hand control back to the emulator. This also happens when a script unexpectingly crashes.

+


+

A bare script looks like this:

+


+

while (true) do

+

  emu.frameadvance();

+

end;

+


+

And is about equal to not running Lua at all. The frameadvance function is the same called internally, so no loss of speed there!

+


+

Bitwise operators:

+


+

Lua does not have bitwise operators, so we supply some for you. These are common bitwise operators, nothing fancy.

+


+

AND(a,b);

+

OR(a,b);

+

XOR(a,b);

+

BIT(n); -- returns a number with only bit n set (1)

+


+

The emulator specific Lua is equal to the one of snes9x, with some platform specific changes (few buttons, for instance). 

+

You can find the reference here: http://dehacked.2y.net/snes9x-lua.html

+

The following is a quick reference, you can go to the snes9x reference for more details.

+


+

To paint stuff on screen, use the gui table. This contains a few predefined functions to manipulate the main window. For any coordinate, 0,0 is the top-left pixel of the window. You have to prevent out-of-bound errors yourself for now. If a color can be passed on, it is a string. HTML-syntax is supported ("#34053D"), as well as a FEW colors ("red", "green", "blue" ...).

+


+

gui.text(x, y, str); -- Print a line to the window, you can use \n for a return but it will only work once

+

gui.pixel(x, y, color); -- plot a pixel at the given coordinate

+

gui.line(x1, y1, x2, y2, color); -- plot a line from x1,y1 to x2,y2

+

gui.box(x1, y1, x2, y2, color); -- draw a square from x1,y1 to x2,y2

+

gui.popup(str); -- pops up a messagebox informing the user of something. Real handy when debugging!

+

gui.getpixel(x,y); -- return the values of the pixel at given position. Returns three numbers of the emulator image before paiting is applied.

+

gui.gdscreenshot(); -- Takes a screen shot of the image and returns it in the form of a string which can be imported by the gd library using the gd.createFromGdStr() function

+

(for more gd functions see DeHackED's reference: http://dehacked.2y.net/snes9x-lua.html)

+


+

PAINTING IS ALWAYS ONE FRAME BEHIND! This is because the painting is done at the creation of the next frame, not while Lua is running.

+


+

Emulator control:

+


+

emu.frameadvance(); -- advances emulation ONE frame

+

emu.pause(); -- same as pressing the pause button

+

emu.speedmode(strMode); -- Supported are "normal","turbo","nothrottle","maximum". But know that except for "normal", all other modes will run as "turbo" for now.

+

emu.wait(); -- skips the emulation of the next frame, in case your script needs to wait for something

+


+

Memory control:

+


+

memory.readbyte(adr); -- read one byte from given address and return it. Besides decimal values Lua also allows the hex notation 0x00FA. In FCEUX reading is done BEFORE the cheats are applied!

+

memory.writebyte(adr, value); -- write one byte to the RAM of the NES. writing is done AFTER the hexeditor receives its values, so if you are freezing an address by Lua, it will not show in the hex editor (but it will in the game :)

+

memory.readbytesigned(adr); -- same as readbyte, except this returns a signed value, rather then an unsigned value.

+

memory.register(adr, function); -- binds a function to an address. The function will be called when an address changes. NOTE THAT THIS IS EXPENSIVE (eg.: slow)! Only one function allowed per address.

+


+

Input control:

+


+

You can read and write input by using the joypad table. A input table has the following (case sensitive) keys, where nil denotes they are not to be pressed: up down left right start select A B

+


+

joypad.read(playern); -- get the input table for the player who's input you want to read (a number!)

+

joypad.write(playern, inputtable); -- set the input for player n. Note that this will overwrite any input from the user, and only when this is used.

+


+

Savestates:

+


+

You can load and save to the predefined savestates 1 ... 9 or create new "anonymous" savestates. You must first create a savestate object, which is your handle to a savestate. Then you can pass this handle on to savestate.load or save to do so.

+


+

savestate.create(n); -- n is optional. When supplied, it will create a savestate for slot n, otherwise a new (anonymous) savestate object is created. Note that this does not yet save or load anything!

+

savestate.load(state); -- load the given savestate

+

savestate.save(state); -- save the given savestate

+


+

For an up-to-date list of functions, see the Lua Functions List.

+

+

Created with the Personal Edition of HelpNDoc: Benefits of a Help Authoring Tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Config.html b/web/help/Config.html index 9c17b87e..97ea86dd 100644 --- a/web/help/Config.html +++ b/web/help/Config.html @@ -1,121 +1,316 @@ - - + + + + + - Config - - - - - - - - - - + + + + + + + + Config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Config

- -
-
- Previous - - Next - -
-
-
-
- -

-

The Config Menu

-


-


-

These chapters explain options under FCEUX's Config menu.

-


-

Menu Items & Sub-menus

-


-

Explains the basic menu items and sub-menu items in the top of the menu.

-


-

GUI

-


-

Settings related to the FCEU emulator window.

-


-


-

Directories

-


-

Sets Directory override assignments.

-


-


-

Input

-


-

Assigns keys/joypad buttons to emulated controllers.

-


-


-

Network Play

-


-

Various settings related to playing over the internet.

-


-

Palette

-


-

Palette options.

-


-

Sound

-


-

Sets sound configuration options.

-


-


-

Timing

-


-

Settings related to emulation timing.

-


-

Video

-


-

Sets video & graphics configuration options.

-


-


-

Movie Options

-


-

Sets options related to playing/recording movie files

-


-


-

Map Hotkeys

-


-

Sets Hotkey assignments.

-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Config

+ +
+ +

+

The Config Menu

+


+


+

These chapters explain options under FCEUX's Config menu.

+


+

Menu Items & Sub-menus

+


+

Explains the basic menu items and sub-menu items in the top of the menu.

+


+

GUI

+


+

Settings related to the FCEU emulator window.

+


+


+

Directories

+


+

Sets Directory override assignments.

+


+


+

Input

+


+

Assigns keys/joypad buttons to emulated controllers.

+


+


+

Network Play

+


+

Various settings related to playing over the internet.

+


+

Palette

+


+

Palette options.

+


+

Sound

+


+

Sets sound configuration options.

+


+


+

Timing

+


+

Settings related to emulation timing.

+


+

Video

+


+

Sets video & graphics configuration options.

+


+


+

Movie Options

+


+

Sets options related to playing/recording movie files

+


+


+

Map Hotkeys

+


+

Sets Hotkey assignments.

+

+

Created with the Personal Edition of HelpNDoc: Easily create PDF Help documents

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/ContextMenuItems.html b/web/help/ContextMenuItems.html index 59e5bb44..1c5c1337 100644 --- a/web/help/ContextMenuItems.html +++ b/web/help/ContextMenuItems.html @@ -1,202 +1,393 @@ - - + + + + + - Context Menu Items - - - - - - - - - - + + + + + + + + Context Menu Items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Context Menu Items

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Context Menu Items

+ +
+

-

Context Menu

-


-

FCEUX includes a context menu that allows commonly used menu functions for various situations.  There are some functions that appear only here.

-


-

This page describes all the possible menu items in each possible context situation.

-


-

No game loaded.

-


-

Appears when no game is loaded.

-


-

Open ROM

-

Same as the File > Open ROM option

-


-

Last ROM used

-

Opens the most recently used file from the Recent Files Menu

-


-

Help

-

Brings up the Getting Started chapter in the help document.

-


-


-

Game Loaded

-


-

Appears when a game is loaded, but not a movie (.fm2).

-


-

Play Movie...

-

Same as the File > Movie > Play Movie menu item.

-


-

Record Movie...

-

Same as the File > Movie > Record Movie menu item.

-


-

Undo savestate

-

If this option is enabled it means the last savestate saved over-wrote a previous savestate file.  This option restores the previous savestate file.

-


-

Redo savestate

-

If this option is in the menu, it means that Undo savestate was recently used to restore a previous savestate.  This reverts that change.

-


-

Rewind to last auto-save

-

Auto-save must be enabled for this menu item to be accessible.  Same as the Load last auto-save Hotkey Item.  It loads the last auto-savestate.  Auto-savestates are created once about every 4 seconds, so this typically has the effect of rewinding emulation.

-


-

Screenshot

-

Same as File > Screenshot.

-


-

Close ROM

-

Same as File > Close

-


-


-

Movie loaded - Read-only

-


-

Appears when a movie is loaded and Read-only mode is set.

-


-

Toggle to read+write

-

Sets Read status to Read+Write.

-


-

Play Movie from Beginning

-

Same as File > Movie > Play from Beginning.  Turns Read status to Read-Only and plays the movie from frame 1.

-


-

Stop Movie Replay

-

Same as File > Movie > Stop Movie.

-


-

View comments and subtitles

-

Opens up the Metadata dialog.  Same as the Metadata button on the Play movie dialog.

-


-

Undo savestate

-

If this option is enabled it means the last savestate saved over-wrote a previous savestate file.  This option restores the previous savestate file.

-


-

Redo savestate

-

If this option is in the menu, it means that Undo savestate was recently used to restore a previous savestate.  This reverts that change.

-


-

Rewind to last auto-save

-

Auto-save must be enabled for this menu item to be accessible.  Same as the Load last auto-save Hotkey Item.  It loads the last auto-savestate.  Auto-savestates are created once about every 4 seconds, so this typically has the effect of rewinding emulation.

-


-

Help

-

Opens the Movie recording chapter of the help document.

-


-


-

Movie loaded - Read + Write

-


-

Toggle to Read-only

-

Sets Read status to Read-Only.

-


-

Play Movie From Beginning

-

Same as File > Movie > Play from Beginning.  Turns Read status to Read-Only and plays the movie from frame 1.

-


-

Stop Movie Recording

-

Same as File > Movie > Stop Movie.

-


-

View comments and subtitles

-

Opens up the Metadata dialog.  Same as the Metadata button on the Play movie dialog.

-


-

Make backup

-

Generates a backup .fm2.  Uses the same file naming system as the auto-movie backup.  (See movie options for details).

-


-

Undo savestate

-

If this option is enabled it means the last savestate saved over-wrote a previous savestate file.  This option restores the previous savestate file.

-


-

Redo savestate

-

If this option is in the menu, it means that Undo savestate was recently used to restore a previous savestate.  This reverts that change.

-


-

Undo loadstate

-

If this option is enabled it was because the Loadstate function was called sometime while the game was loaded.  This function restores the game state to where it was before loadstate was called.

-


-

Redo loadstate

-

If Undo loadstate was called, this option is available.  It reverts the change and restores the game back to the point it was when loadstate was called.

-


-

Help

-

Opens the Movie recording chapter of the help document.

-


-

Additional items may also appear related to these situations:

-


-

Lua

-


-

Load last Lua

-

If there is at least 1 filename in the Recent Lua Files menu this calls the most recently used Lua script file.  Has the same effect as the File > Lua > Reload Lua Script menu item.

-


-

Stop Lua

-

If a Lua script is currently loaded this option is available.  Same as File > Lua > Stop Lua Script.

-


-

Hide Menu

-


-

Unhide menu

-

If the main FCEUX menu is hidden this option is available. Restores the main menu.

-


-

Subtitles

-


-

If a movie is loaded and has subtitles:

-
    -
  • a toggle subtitles option will be in the menu
  • -
  • a Dump to SRT file option will be available.  This dumps the subtitles to a standard subtitle file compatible with A/V containers such as .mkv
  • +

    Context Menu

    +


    +

    FCEUX includes a context menu that allows commonly used menu functions for various situations.  There are some functions that appear only here.

    +


    +

    This page describes all the possible menu items in each possible context situation.

    +


    +

    No game loaded.

    +


    +

    Appears when no game is loaded.

    +


    +

    Open ROM

    +

    Same as the File > Open ROM option

    +


    +

    Last ROM used

    +

    Opens the most recently used file from the Recent Files Menu

    +


    +

    Help

    +

    Brings up the Getting Started chapter in the help document.

    +


    +


    +

    Game Loaded

    +


    +

    Appears when a game is loaded, but not a movie (.fm2).

    +


    +

    Play Movie...

    +

    Same as the File > Movie > Play Movie menu item.

    +


    +

    Record Movie...

    +

    Same as the File > Movie > Record Movie menu item.

    +


    +

    Undo savestate

    +

    If this option is enabled it means the last savestate saved over-wrote a previous savestate file.  This option restores the previous savestate file.

    +


    +

    Redo savestate

    +

    If this option is in the menu, it means that Undo savestate was recently used to restore a previous savestate.  This reverts that change.

    +


    +

    Rewind to last auto-save

    +

    Auto-save must be enabled for this menu item to be accessible.  Same as the Load last auto-save Hotkey Item.  It loads the last auto-savestate.  Auto-savestates are created once about every 4 seconds, so this typically has the effect of rewinding emulation.

    +


    +

    Screenshot

    +

    Same as File > Screenshot.

    +


    +

    Close ROM

    +

    Same as File > Close

    +


    +


    +

    Movie loaded - Read-only

    +


    +

    Appears when a movie is loaded and Read-only mode is set.

    +


    +

    Toggle to read+write

    +

    Sets Read status to Read+Write.

    +


    +

    Play Movie from Beginning

    +

    Same as File > Movie > Play from Beginning.  Turns Read status to Read-Only and plays the movie from frame 1.

    +


    +

    Stop Movie Replay

    +

    Same as File > Movie > Stop Movie.

    +


    +

    View comments and subtitles

    +

    Opens up the Metadata dialog.  Same as the Metadata button on the Play movie dialog.

    +


    +

    Undo savestate

    +

    If this option is enabled it means the last savestate saved over-wrote a previous savestate file.  This option restores the previous savestate file.

    +


    +

    Redo savestate

    +

    If this option is in the menu, it means that Undo savestate was recently used to restore a previous savestate.  This reverts that change.

    +


    +

    Rewind to last auto-save

    +

    Auto-save must be enabled for this menu item to be accessible.  Same as the Load last auto-save Hotkey Item.  It loads the last auto-savestate.  Auto-savestates are created once about every 4 seconds, so this typically has the effect of rewinding emulation.

    +


    +

    Help

    +

    Opens the Movie recording chapter of the help document.

    +


    +


    +

    Movie loaded - Read + Write

    +


    +

    Toggle to Read-only

    +

    Sets Read status to Read-Only.

    +


    +

    Play Movie From Beginning

    +

    Same as File > Movie > Play from Beginning.  Turns Read status to Read-Only and plays the movie from frame 1.

    +


    +

    Stop Movie Recording

    +

    Same as File > Movie > Stop Movie.

    +


    +

    View comments and subtitles

    +

    Opens up the Metadata dialog.  Same as the Metadata button on the Play movie dialog.

    +


    +

    Make backup

    +

    Generates a backup .fm2.  Uses the same file naming system as the auto-movie backup.  (See movie options for details).

    +


    +

    Undo savestate

    +

    If this option is enabled it means the last savestate saved over-wrote a previous savestate file.  This option restores the previous savestate file.

    +


    +

    Redo savestate

    +

    If this option is in the menu, it means that Undo savestate was recently used to restore a previous savestate.  This reverts that change.

    +


    +

    Undo loadstate

    +

    If this option is enabled it was because the Loadstate function was called sometime while the game was loaded.  This function restores the game state to where it was before loadstate was called.

    +


    +

    Redo loadstate

    +

    If Undo loadstate was called, this option is available.  It reverts the change and restores the game back to the point it was when loadstate was called.

    +


    +

    Help

    +

    Opens the Movie recording chapter of the help document.

    +


    +

    Additional items may also appear related to these situations:

    +


    +

    Lua

    +


    +

    Load last Lua

    +

    If there is at least 1 filename in the Recent Lua Files menu this calls the most recently used Lua script file.  Has the same effect as the File > Lua > Reload Lua Script menu item.

    +


    +

    Stop Lua

    +

    If a Lua script is currently loaded this option is available.  Same as File > Lua > Stop Lua Script.

    +


    +

    Hide Menu

    +


    +

    Unhide menu

    +

    If the main FCEUX menu is hidden this option is available. Restores the main menu.

    +


    +

    Subtitles

    +


    +

    If a movie is loaded and has subtitles:

    +
      +
    • a toggle subtitles option will be in the menu
    • +
    • a Dump to SRT file option will be available.  This dumps the subtitles to a standard subtitle file compatible with A/V containers such as .mkv
    -


    -


    +


    +


    -

    Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

    -
- - + + +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + - -
- - diff --git a/web/help/Covertfcm.html b/web/help/Covertfcm.html index 1ae47fa4..91f13403 100644 --- a/web/help/Covertfcm.html +++ b/web/help/Covertfcm.html @@ -1,78 +1,269 @@ - - + + + + + - Convert fcm - - - - - - - - - - + + + + + + + + Convert fcm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Convert fcm

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Converting .fcm to .fm2 files

-


-

FCEUX uses a new movie file format (.fm2).  In order to use movie files frame previous FCE Ultra versions (.fcm) you will need to convert to .fm2 first.

-


-

Using .fcm Convert

-


-

To use it simply highlight it.  Then select the .fcm you wish to convert (or shift+click to select multiple .fcm files).  Then click Open to have the select files converted.  All files selected will have a matching .fm2 file copied into the same folder.

-

-

Created with the Personal Edition of HelpNDoc: Full-featured Help generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Convert fcm

+ +
+ +

+

Converting .fcm to .fm2 files

+


+

FCEUX uses a new movie file format (.fm2).  In order to use movie files frame previous FCE Ultra versions (.fcm) you will need to convert to .fm2 first.

+


+

Using .fcm Convert

+


+

To use it simply highlight it.  Then select the .fcm you wish to convert (or shift+click to select multiple .fcm files).  Then click Open to have the select files converted.  All files selected will have a matching .fm2 file copied into the same folder.

+

+

Created with the Personal Edition of HelpNDoc: Free EPub and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/CustomizingthroughtheConfigFil.html b/web/help/CustomizingthroughtheConfigFil.html index 5eb70869..9592cdb8 100644 --- a/web/help/CustomizingthroughtheConfigFil.html +++ b/web/help/CustomizingthroughtheConfigFil.html @@ -1,121 +1,312 @@ - - + + + + + - Customizing through the Config File - - - - - - - - - - + + + + + + + + Customizing through the Config File + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Customizing through the Config File

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Customizing through the Config File

-


-


-

There are some options that can only be done by directly editing the config (fceux.cfg) file.  All of those options are documented here.

-

The .cfg file is a text file and can be opened by any text editor (just as wordpad).

-


-


-

Emulator background Color when Graphics Background is disabled

-


-

gNoBGFillColor

-


-

When you disable the backgrounds (Config > Display > Graphics: GB), the default color is black.  You can change that color by modifying this value.  By default it is 255 (black).

-


-


-

Debugger

-


-

debuggerFontSize 15

-


-

This value determines the size of the "Courier" font used by Debugger and Trace Logger. By default it is 15.

-


-


-

Hex Editor

-


-

hexeditorFontSize 15

-


-

This value determines the size of the "Courier" font used by Hex Editor. By default it is 15.

-


-


-

HexRowHeightBorder 0

-


-

This value determines the number of pixels between each row of values in the Hex Editor.  By default it is 0.

-


-


-

HexBackColorR 255

-

HexBackColorG 255

-

HexBackColorB 255

-


-

HexForeColorR 0

-

HexForeColorG 0

-

HexForeColorB 0

-


-

HexFreezeColorR 0

-

HexFreezeColorG 0

-

HexFreezeColorB 255

-


-

These values allows are the Hex Editor color scheme values (RGB).  The background color is 255,255,255 (white) by default.  The foreground color (text) is 0,0,0 (black) by default. When an address is frozen it is 0,0,255 (blue) by default.

-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Customizing through the Config File

+ +
+ +

+

Customizing through the Config File

+


+


+

There are some options that can only be done by directly editing the config (fceux.cfg) file.  All of those options are documented here.

+

The .cfg file is a text file and can be opened by any text editor (just as wordpad).

+


+


+

Emulator background Color when Graphics Background is disabled

+


+

gNoBGFillColor

+


+

When you disable the backgrounds (Config > Display > Graphics: GB), the default color is black.  You can change that color by modifying this value.  By default it is 255 (black).

+


+


+

Debugger

+


+

debuggerFontSize 15

+


+

This value determines the size of the "Courier" font used by Debugger and Trace Logger. By default it is 15.

+


+


+

Hex Editor

+


+

hexeditorFontSize 15

+


+

This value determines the size of the "Courier" font used by Hex Editor. By default it is 15.

+


+


+

HexRowHeightBorder 0

+


+

This value determines the number of pixels between each row of values in the Hex Editor.  By default it is 0.

+


+


+

HexBackColorR 255

+

HexBackColorG 255

+

HexBackColorB 255

+


+

HexForeColorR 0

+

HexForeColorG 0

+

HexForeColorB 0

+


+

HexFreezeColorR 0

+

HexFreezeColorG 0

+

HexFreezeColorB 255

+


+

These values allows are the Hex Editor color scheme values (RGB).  The background color is 255,255,255 (white) by default.  The foreground color (text) is 0,0,0 (black) by default. When an address is frozen it is 0,0,255 (blue) by default.

+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create EPub books

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Debug.html b/web/help/Debug.html index 249818e2..9989d0de 100644 --- a/web/help/Debug.html +++ b/web/help/Debug.html @@ -1,107 +1,302 @@ - - + + + + + - Debug - - - - - - - - - - + + + + + + + + Debug + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Debug

- -
-
- Previous - - Next - -
-
-
-
- -

-

Debug

-


-

Guides for the specific tools and settings under FCEUX's Debug menu.

-


-

Debugger

-


-

A tool for looking at game instructions in assembly language. With experience,

-

one can use it to fix game patching errors, or find RAM and Game Genie codes.

-


-

PPU Viewer

-


-

A tool that displays the current PPU contents and related information. The PPU

-

viewer allows you to view the graphic squares that make up what's displayed.

-


-

Name Table Viewer

-


-

A tool for displaying the current Name Table contents. Helps to isolate PPU

-

and tile information, which allows the debugger to be used to check PPU coding.

-


-

Hex Editor

-


-

A tool for displaying a game's RAM contents and for memory poking. Also allows

-

for reading in the raw PPU data, copy/paste-ing RAM, and visually debugging RAM.

-


-

Trace Logger

-


-

Captures assembly code instructions and outputs them to a file or the window. Very

-

useful for analyzing code, finding crash addresses, fixing transferred routines, and

-

for comparing routine function between a game and a persistently buggy NSF.

-


-

Code/Data Logger

-


-

Allows you to extract the data used by a game. Make patch demos, find data

-

loaded by a game around a certain point, or just map out a single routine run.

-


-

Game Genie Encoder/Decoder

-


-

Allows you to add Game Genie codes to the Cheats menu, decode existing

-

ones to their component information, and (re)create a code with desired values.

-


-

-

Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Debug

+ +
+ +

+

Debug

+


+

Guides for the specific tools and settings under FCEUX's Debug menu.

+


+

Debugger

+


+

A tool for looking at game instructions in assembly language. With experience,

+

one can use it to fix game patching errors, or find RAM and Game Genie codes.

+


+

PPU Viewer

+


+

A tool that displays the current PPU contents and related information. The PPU

+

viewer allows you to view the graphic squares that make up what's displayed.

+


+

Name Table Viewer

+


+

A tool for displaying the current Name Table contents. Helps to isolate PPU

+

and tile information, which allows the debugger to be used to check PPU coding.

+


+

Hex Editor

+


+

A tool for displaying a game's RAM contents and for memory poking. Also allows

+

for reading in the raw PPU data, copy/paste-ing RAM, and visually debugging RAM.

+


+

Trace Logger

+


+

Captures assembly code instructions and outputs them to a file or the window. Very

+

useful for analyzing code, finding crash addresses, fixing transferred routines, and

+

for comparing routine function between a game and a persistently buggy NSF.

+


+

Code/Data Logger

+


+

Allows you to extract the data used by a game. Make patch demos, find data

+

loaded by a game around a certain point, or just map out a single routine run.

+


+

Game Genie Encoder/Decoder

+


+

Allows you to add Game Genie codes to the Cheats menu, decode existing

+

ones to their component information, and (re)create a code with desired values.

+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Debugger.html b/web/help/Debugger.html index 95363187..00276440 100644 --- a/web/help/Debugger.html +++ b/web/help/Debugger.html @@ -1,304 +1,495 @@ - - + + + + + - Debugger - - - - - - - - - - + + + + + + + + Debugger + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Debugger

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Debugger

+ +
+

-

Debugger

-


-


-

Introduction

-


-

The debugger is a tool for inspecting and manipulating machine instructions and their execution. The debugger window has several components:

-
    -
  • Execution - a small set of controls for controlling the execution of code.
  • -
  • CPU State - display of registers, flags, the stack, cycles and instructions counters, and also the PPU state.
  • -
  • Memory disassembly - displays a disassembly of the bytes currently accessible by the CPU data bus.
  • -
  • Breakpoints - a list of breakpoints for debugging.
  • -
  • Bookmarks - a list of bookmarked addresses for quick navigation.
  • -
  • Other - buttons for controlling symbolic debugging, rom patching, etc.
  • +

    Debugger

    +


    +


    +

    Introduction

    +


    +

    The debugger is a tool for inspecting and manipulating machine instructions and their execution. The debugger window has several components:

    +
      +
    • Execution - a small set of controls for controlling the execution of code.
    • +
    • CPU State - display of registers, flags, the stack, cycles and instructions counters, and also the PPU state.
    • +
    • Memory disassembly - displays a disassembly of the bytes currently accessible by the CPU data bus.
    • +
    • Breakpoints - a list of breakpoints for debugging.
    • +
    • Bookmarks - a list of bookmarked addresses for quick navigation.
    • +
    • Other - buttons for controlling symbolic debugging, rom patching, etc.
    -


    -


    -

    Execution and CPU State

    -


    -

    Execution is controlled by the set of buttons at the top-middle of the window. These allow you to break (pause) execution and inspect the current state of the NES.

    -


    -

    When an NES ROM is opened, it will be normally be running right away (unless you manually pause the emulator before loading). Most of the debugger window does not update while the game is running. To begin debugging you may click one of the buttons that will break (pause) execution, such as "Step Into".

    -


    -
      -
    • Run - runs the program continuously until the next breakpoint is hit, or the emulator is paused manually. The same effect can be achieved by pressing the Pause hotkey which will unpause emulator when it's paused.
    • -
    • Step Into - runs one instruction and then breaks.
    • -
    • Step Out - attempt to run until the current subroutine ends with an RTS; in some cases will behave the same as Run.
    • -
    • Step Over - runs one instruction, unless it is a JSR instruction, which will run until its RTS.
    • -
    • Run Line - runs one scanline before breaking.
    • -
    • 128 Lines - runs 128 scanlines before breaking.
    • +


      +


      +

      Execution and CPU State

      +


      +

      Execution is controlled by the set of buttons at the top-middle of the window. These allow you to break (pause) execution and inspect the current state of the NES.

      +


      +

      When an NES ROM is opened, it will be normally be running right away (unless you manually pause the emulator before loading). Most of the debugger window does not update while the game is running. To begin debugging you may click one of the buttons that will break (pause) execution, such as "Step Into".

      +


      +
        +
      • Run - runs the program continuously until the next breakpoint is hit, or the emulator is paused manually. The same effect can be achieved by pressing the Pause hotkey which will unpause emulator when it's paused.
      • +
      • Step Into - runs one instruction and then breaks.
      • +
      • Step Out - attempt to run until the current subroutine ends with an RTS; in some cases will behave the same as Run.
      • +
      • Step Over - runs one instruction, unless it is a JSR instruction, which will run until its RTS.
      • +
      • Run Line - runs one scanline before breaking.
      • +
      • 128 Lines - runs 128 scanlines before breaking.
      -


      -

      The Pause hotkey will break execution or resume it. The Frame Advance hotkey will run the emulator for one frame and then break.

      -


      -

      When execution is paused, the disassembly view will begin with the memory near the current program counter location (PC). The ">" mark shows the line which will be executed next. You can scroll the disassembly up or down (using scrollbar or mouse wheel) to observe the code. Then you can click "Seek PC" to return to the program counter at any time.

      -


      -

      You can also use "Seek To" button that will navigate to the specified address. Either type a hexadecimal address to the text field or simply left-click on any address in the Disassembly window.

      -


      -
      - - - +


      +

      The Pause hotkey will break execution or resume it. The Frame Advance hotkey will run the emulator for one frame and then break.

      +


      +

      When execution is paused, the disassembly view will begin with the memory near the current program counter location (PC). The ">" mark shows the line which will be executed next. You can scroll the disassembly up or down (using scrollbar or mouse wheel) to observe the code. Then you can click "Seek PC" to return to the program counter at any time.

      +


      +

      You can also use "Seek To" button that will navigate to the specified address. Either type a hexadecimal address to the text field or simply left-click on any address in the Disassembly window.

      +


      +
      +

      HINT: When entering the address manually, these convenient strings may be used instead of the hexadecimal memory address:

      -

      NES special addresses:

      -
        -
      • NMI/VBL - non-maskable interrupt vector (at FFFA)
      • -
      • RST     - reset vector (at FFFC)
      • -
      • IRQ     - interrupt vector (at FFFE)
      • -
      -

      FDS special addresses:

      -
        -
      • NMI1 - non-maskable interrupt vector (at DFF6)
      • -
      • NMI2 - non-maskable interrupt vector (at DFF8)
      • -
      • NMI3 - non-maskable interrupt vector (at DFFA)
      • -
      • RST  - reset vector (at DFFC)
      • -
      • IRQ  - interrupt vector (at DFFE)
      • -
      -

      NSF special addresses:

      -
        -
      • LOAD - NSF LOAD address
      • -
      • INIT - NSF INIT address
      • -
      • PLAY - NSF PLAY address
      • -
      -
      + + +
      +

      HINT: When entering the address manually, these convenient strings may be used instead of the hexadecimal memory address:

      +

      NES special addresses:

      +
        +
      • NMI/VBL - non-maskable interrupt vector (at FFFA)
      • +
      • RST     - reset vector (at FFFC)
      • +
      • IRQ     - interrupt vector (at FFFE)
      • +
      +

      FDS special addresses:

      +
        +
      • NMI1 - non-maskable interrupt vector (at DFF6)
      • +
      • NMI2 - non-maskable interrupt vector (at DFF8)
      • +
      • NMI3 - non-maskable interrupt vector (at DFFA)
      • +
      • RST  - reset vector (at DFFC)
      • +
      • IRQ  - interrupt vector (at DFFE)
      • +
      +

      NSF special addresses:

      +
        +
      • LOAD - NSF LOAD address
      • +
      • INIT - NSF INIT address
      • +
      • PLAY - NSF PLAY address
      • +
      +
      -


      -

      While execution is broken (emulation is paused), the program counter (PC) can be edited, as well as the three registers A/X/Y, and the status flags. Normally they should be left as-is, but changing them at runtime can be useful for more advanced debugging.

      -


      -

      The contents of memory starting at the stack pointer (somewhere in the range $0100-01FF) is displayed in the Stack frame below the A/X/Y registers.

      -


      -

      The current PPU memory address, sprite memory address, scanline, and rendering pixel are displayed below the stack and status flags. Examples of Scanline number: -1 means Prerender time, 240 is Idle scanline, 0-239 are visible scanlines, 241-260/310 are VBlank scanlines.

      -


      -

      To the right from the PPU section there's Cycles counter and Instructions counter that keep counting while the game is running. You can use the information for keeping statistics, for code profiling or writing PPU-synchronized code (e.g. raster effects). You can also make the debugger break automatically based on the counters values. The "Reset counters" button resets both counters to 0. You can also access the counters via Lua.

      -


      -


      -

      Disassembly

      -


      -

      This large frame takes up the left side of the debugger window. It displays the current contents of memory accessible by the CPU with an automatic disassembly of that data into assembly instructions. The following memory ranges may contain useful data for inspection:

      -
        -
      • 0000-00FF - zero page (RAM)
      • -
      • 0100-01FF - stack (RAM)
      • -
      • 0200-07FF - RAM
      • -
      • 4018-FFFF - mapper controlled (ROM or RAM, may be bankswitched)
      • +


        +

        While execution is broken (emulation is paused), the program counter (PC) can be edited, as well as the three registers A/X/Y, and the status flags. Normally they should be left as-is, but changing them at runtime can be useful for more advanced debugging.

        +


        +

        The contents of memory starting at the stack pointer (somewhere in the range $0100-01FF) is displayed in the Stack frame below the A/X/Y registers.

        +


        +

        The current PPU memory address, sprite memory address, scanline, and rendering pixel are displayed below the stack and status flags. Examples of Scanline number: -1 means Prerender time, 240 is Idle scanline, 0-239 are visible scanlines, 241-260/310 are VBlank scanlines.

        +


        +

        To the right from the PPU section there's Cycles counter and Instructions counter that keep counting while the game is running. You can use the information for keeping statistics, for code profiling or writing PPU-synchronized code (e.g. raster effects). You can also make the debugger break automatically based on the counters values. The "Reset counters" button resets both counters to 0. You can also access the counters via Lua.

        +


        +


        +

        Disassembly

        +


        +

        This large frame takes up the left side of the debugger window. It displays the current contents of memory accessible by the CPU with an automatic disassembly of that data into assembly instructions. The following memory ranges may contain useful data for inspection:

        +
          +
        • 0000-00FF - zero page (RAM)
        • +
        • 0100-01FF - stack (RAM)
        • +
        • 0200-07FF - RAM
        • +
        • 4018-FFFF - mapper controlled (ROM or RAM, may be bankswitched)
        -


        -

        Memory contents are displayed in this form:

        -


        -

        0F:C0A8:24 1F     BIT $001F = #$80

        -

        bb:mmmm:dd dd dd  iiiiiiiiiiiii...

        -


        -
          -
        • bb - 16k iNES bank, designates which 16k bank from the iNES file is mapped here. Note that the number may be not the same as the actual hardware bank of the mapper.
        • -
        • mmmm - physical address on the NES CPU data bus.
        • -
        • dd - data bytes belonging to the instruction beginning at this address.
        • -
        • iiii - assembly description of the instruction, possibly with symbolic decoration.
        • +


          +

          Memory contents are displayed in this form:

          +


          +

          0F:C0A8:24 1F     BIT $001F = #$80

          +

          bb:mmmm:dd dd dd  iiiiiiiiiiiii...

          +


          +
            +
          • bb - 16k iNES bank, designates which 16k bank from the iNES file is mapped here. Note that the number may be not the same as the actual hardware bank of the mapper.
          • +
          • mmmm - physical address on the NES CPU data bus.
          • +
          • dd - data bytes belonging to the instruction beginning at this address.
          • +
          • iiii - assembly description of the instruction, possibly with symbolic decoration.
          -


          -

          When debugging an NSF program, the bank designation will be a 4k NSF bank instead of the 16k iNES bank.

          -


          -

          A single instruction may be one to three bytes, and will all appear on the line before the assembly code description of that instruction. An instruction with "= #$xx" at the end conveniently indicates the value currently in memory at the address referenced by the instruction.

          -


          -

          Hovering the mouse over the disassembly will display at the bottom of the window more detailed information about the location of this code in the iNES file.

          -


          -

          There is narrow column to the left of the Disassembly window. Left clicking on this column will open the Inline Assembler, which allows you to patch the ROM at runtime. Right clicking on this column will open the Hex Editor, which allows you to directly edit the ROM. Middle-clicking on this column will bring up the Game Genie Encoder at that address, so you can easily make Game Genie codes.

          -

          Also, when Code/Data Logger is running, this small column displays whether the respective line of the disassembled memory was executed ("c") or it was read as Data ("d"), or it wasn't logged yet (empty space). This way you can easily distinguish which branches of the game code were executed and which weren't.

          -


          -


          -

          Symbolic Debugging

          -


          -

          FCEUX allows you to label any address of RAM or ROM with a human-readable symbolic name.

          -

          For example, when you've figured out that at the address $C022 there's a subroutine which refills player HP, you can right-click the address and type a name like "AddHealthpoints". You can also add a comment, which will be seen while browsing the code near this address. From now on, the address will be substituted by the name everywhere - in all instructions referencing this address, in Hex Editor window, in the log produced by Trace Logger. E.g., JSR $C022 will look like JSR AddHealthpoints.

          -


          -

          When entering the name, you can use any symbols except #. It's also recommended to avoid whitespaces in names.

          -

          To rename an address, just right-click the name.

          -


          -

          The data for Symbolic Debugging is stored in NL files in the same folder as the ROM. You can edit the files in any text editor (to reload all NL files of the currently active ROM file press the "Reload Symbols" button), but it's more convenient to use right-clicks.

          -


          -

          You can enable and disable symbolic debugging by clicking the checkbox "Symbolic debug" in the lower right corner. In general, there's no need to disable this feature. If you need to see the actual address which got substituted by a name, you can simply left-click the name and watch its address in the "Seek To" text field. This also works when clicking a name in the Trace Logger window.

          -


          -


          -

          Breakpoints

          -


          -

          Breakpoints will automatically break execution when chosen conditions are met. To create a breakpoint, click the Add button in the Breakpoints frame in the upper right corner of the debugger.

          -


          -

          Each breakpoint has an address range to watch. Use only the left address field if you wish to watch a single byte address. When entering the address of a breakpoint, you can also use the aforementioned convenient strings (such as IRQ) instead of hexadecimal memory addresses.

          -


          -

          Check one or more of the options to watch for Read, Write, or Execute at the given address. Note that fetching of code from an address will not break as a Read; so use the Execute box for this case. Breakpoints can be given a name that will appear in the breakpoints list. The condition field can be used to break only on particular conditions; see "Conditional Breakpoints" below.

          -


          -

          Double click on a breakpoint in the Breakpoints list to quickly disable or enable this breakpoint. So you don't have to delete breakpoints to stop them from causing the debugger to halt the game.

          -


          -

          A special kind of breakpoints with the "Forbid" option will prevent any breakpoints from occurring within the specified memory address range. This can be enabled and disabled like other breakpoints.

          -


          -

          A quicker way to add PC breakpoints is to double click on any address in the Disassembly when you want to set the breakpoint to that address. Example: when you need to quickly advance emulation to a given line of code, double-click on the address part of the line, and the "Add Execute breakpoint here" dialog will appear, just click "OK" and then hit "Run", Debugger will break at this line of code.

          -


          -

          There is also an option to Break on Bad Opcodes, which will halt execution if a bad instruction opcode is reached.

          -


          -

          Finally, you can make the debugger break after executing a certain number of instructions or CPU cycles.

          -


          -

          More advanced breakpoints conditions and full automation may be achieved through Lua script breakpoints. See the Lua reference for more information.

          -


          -

          Breakpoints are listed in the following form:

          -


          -

          aaaa EmRWXF nnnn cccc

          -

          or

          -

          aaaa-aaaa EmRWXF nnnn cccc

          -


          -
            -
          • aaaa - address of breakpoint
          • -
          • E    - enabled
          • -
          • m    - memory area: C = CPU, P = PPU, S = sprite
          • -
          • R    - read
          • -
          • W    - write
          • -
          • X    - execute
          • -
          • F    - Forbid
          • -
          • nnnn - (optional) name of breakpoint
          • -
          • nnnn - (optional) condition of breakpoint
          • +


            +

            When debugging an NSF program, the bank designation will be a 4k NSF bank instead of the 16k iNES bank.

            +


            +

            A single instruction may be one to three bytes, and will all appear on the line before the assembly code description of that instruction. An instruction with "= #$xx" at the end conveniently indicates the value currently in memory at the address referenced by the instruction.

            +


            +

            Hovering the mouse over the disassembly will display at the bottom of the window more detailed information about the location of this code in the iNES file.

            +


            +

            There is narrow column to the left of the Disassembly window. Left clicking on this column will open the Inline Assembler, which allows you to patch the ROM at runtime. Right clicking on this column will open the Hex Editor, which allows you to directly edit the ROM. Middle-clicking on this column will bring up the Game Genie Encoder at that address, so you can easily make Game Genie codes.

            +

            Also, when Code/Data Logger is running, this small column displays whether the respective line of the disassembled memory was executed ("c") or it was read as Data ("d"), or it wasn't logged yet (empty space). This way you can easily distinguish which branches of the game code were executed and which weren't.

            +


            +


            +

            Symbolic Debugging

            +


            +

            FCEUX allows you to label any address of RAM or ROM with a human-readable symbolic name.

            +

            For example, when you've figured out that at the address $C022 there's a subroutine which refills player HP, you can right-click the address and type a name like "AddHealthpoints". You can also add a comment, which will be seen while browsing the code near this address. From now on, the address will be substituted by the name everywhere - in all instructions referencing this address, in Hex Editor window, in the log produced by Trace Logger. E.g., JSR $C022 will look like JSR AddHealthpoints.

            +


            +

            When entering the name, you can use any symbols except #. It's also recommended to avoid whitespaces in names.

            +

            To rename an address, just right-click the name.

            +


            +

            The data for Symbolic Debugging is stored in NL files in the same folder as the ROM. You can edit the files in any text editor (to reload all NL files of the currently active ROM file press the "Reload Symbols" button), but it's more convenient to use right-clicks.

            +


            +

            You can enable and disable symbolic debugging by clicking the checkbox "Symbolic debug" in the lower right corner. In general, there's no need to disable this feature. If you need to see the actual address which got substituted by a name, you can simply left-click the name and watch its address in the "Seek To" text field. This also works when clicking a name in the Trace Logger window.

            +


            +


            +

            Breakpoints

            +


            +

            Breakpoints will automatically break execution when chosen conditions are met. To create a breakpoint, click the Add button in the Breakpoints frame in the upper right corner of the debugger.

            +


            +

            Each breakpoint has an address range to watch. Use only the left address field if you wish to watch a single byte address. When entering the address of a breakpoint, you can also use the aforementioned convenient strings (such as IRQ) instead of hexadecimal memory addresses.

            +


            +

            Check one or more of the options to watch for Read, Write, or Execute at the given address. Note that fetching of code from an address will not break as a Read; so use the Execute box for this case. Breakpoints can be given a name that will appear in the breakpoints list. The condition field can be used to break only on particular conditions; see "Conditional Breakpoints" below.

            +


            +

            Double click on a breakpoint in the Breakpoints list to quickly disable or enable this breakpoint. So you don't have to delete breakpoints to stop them from causing the debugger to halt the game.

            +


            +

            A special kind of breakpoints with the "Forbid" option will prevent any breakpoints from occurring within the specified memory address range. This can be enabled and disabled like other breakpoints.

            +


            +

            A quicker way to add PC breakpoints is to double click on any address in the Disassembly when you want to set the breakpoint to that address. Example: when you need to quickly advance emulation to a given line of code, double-click on the address part of the line, and the "Add Execute breakpoint here" dialog will appear, just click "OK" and then hit "Run", Debugger will break at this line of code.

            +


            +

            There is also an option to Break on Bad Opcodes, which will halt execution if a bad instruction opcode is reached.

            +


            +

            Finally, you can make the debugger break after executing a certain number of instructions or CPU cycles.

            +


            +

            More advanced breakpoints conditions and full automation may be achieved through Lua script breakpoints. See the Lua reference for more information.

            +


            +

            Breakpoints are listed in the following form:

            +


            +

            aaaa EmRWXF nnnn cccc

            +

            or

            +

            aaaa-aaaa EmRWXF nnnn cccc

            +


            +
              +
            • aaaa - address of breakpoint
            • +
            • E    - enabled
            • +
            • m    - memory area: C = CPU, P = PPU, S = sprite
            • +
            • R    - read
            • +
            • W    - write
            • +
            • X    - execute
            • +
            • F    - Forbid
            • +
            • nnnn - (optional) name of breakpoint
            • +
            • nnnn - (optional) condition of breakpoint
            -


            -


            -

            Conditional Breakpoints

            -


            -

            Breakpoints may also have a conditional statement that causes them to execute only if that statement evaluates to true. The conditional breakpoint grammar has this form:

            -


            -
              -
            • Connect   -> Compare { ('||' | '&&') Compare }
            • -
            • Compare   -> Sum { ('==' | '!=' | '<=' | '>=' | '<' | '>') Sum }
            • -
            • Sum       -> Product { ('+' | '-') Product }
            • -
            • Product   -> Primitive { ('*' | '/') Primitive }
            • -
            • Primitive -> Number | Address | Register | Flag | PC Bank | Data Bank | '(' Connect ')'
            • -
            • Number    -> '#' [0123456789ABCDEF]*
            • -
            • Address   -> '$' [0123456789ABCDEF]* | '$' '[' Connect ']'
            • -
            • Register  -> 'A' | 'X' | 'Y' | 'P'
            • -
            • Flag      -> 'N' | 'C' | 'Z' | 'I' | 'B' | 'V' | 'D' | 'U'
            • -
            • PC Bank   -> 'K'
            • -
            • Data Bank   -> 'T'
            • -
            • Read/Write Value   -> 'R' | 'W'
            • +


              +


              +

              Conditional Breakpoints

              +


              +

              Breakpoints may also have a conditional statement that causes them to execute only if that statement evaluates to true. The conditional breakpoint grammar has this form:

              +


              +
                +
              • Connect   -> Compare { ('||' | '&&') Compare }
              • +
              • Compare   -> Sum { ('==' | '!=' | '<=' | '>=' | '<' | '>') Sum }
              • +
              • Sum       -> Product { ('+' | '-') Product }
              • +
              • Product   -> Primitive { ('*' | '/') Primitive }
              • +
              • Primitive -> Number | Address | Register | Flag | PC Bank | Data Bank | '(' Connect ')'
              • +
              • Number    -> '#' [0123456789ABCDEF]*
              • +
              • Address   -> '$' [0123456789ABCDEF]* | '$' '[' Connect ']'
              • +
              • Register  -> 'A' | 'X' | 'Y' | 'P'
              • +
              • Flag      -> 'N' | 'C' | 'Z' | 'I' | 'B' | 'V'
              • +
              • PC Bank   -> 'K'
              • +
              • Data Bank   -> 'T'
              -


              -

              The parser is very strict. All numbers are hexadecimal. Always prefix a number with # for an immediate value, or $ for a memory address. If a memory address needs to be calculated use $[] with the calculation inside the brackets.

              -


              -

              Registers A/X/Y are 8-bit unsigned values. Register P is the 16-bit program counter.

              -

              Flags evaluate to 1 if set, 0 if clear. (U is the unused bit of the status register, and D is the unused decimal flag.)

              -

              For instructions that read or write a single byte (e.g. LDA, STY, PHA, ASL abs), condition R evaluates to the value that will be read by the instruction, and condition W evaluates to the value that will be written.

              -


              -

              Connecting operators || or && combine boolean terms. Parentheses dictate order of operations.

              -


              -

              Example conditions:

              -


              -

              Break only if register A is less than value at memory address $0005:

              -

              A < $0005

              -


              -

              Break only if the value at the indirect address is not equal to FF:

              -

              #FF != $[$10+($11*#100)]

              -


              -

              Break only if flag N is clear or A is not equal to 00:

              -

              (N==#0 || A!=#0)

              -


              -

              Break only when accessing a data from bank 2 (the condiition is relevant when using with Read/Write-type breakpoints):

              -

              T==#2

              -


              -


              -

              Bookmarks

              -


              -

              A list of bookmarked addresses can be kept in the Address Bookmarks frame to make memory navigation easier. Simply type a hexadecimal address (or a convenient string, such as "NMI") and click "Add" to add it to your bookmarks. Alternatively, just left-click any address in the Disassembly window, and the address will appear in the Bookmark Add field, so you don't have to type it.

              -

              Next time you wish to go to this address just double click on the bookmark.

              -

              You can also name bookmarks.

              -

              When you exit the emulator, bookmarks are saved in a .deb file named after the ROM of the debugged game. Next time you return to debugging the game, the list of bookmarks will be automatically loaded from the file.

              -


              -


              -

              Inline Assembler

              -


              -

              Open the inline assembler by left-clicking in the empty column to the left of the memory view.

              -


              -

              The starting memory address is displayed in the PC field at the top of the inline assembler window. Type a line of assembly to add in the empty field just below this, and hit enter. The assembled code of your patch will appear below as you enter each line.

              -


              -

              Click Apply to apply your patch to the ROM in memory. Click Undo to remove the last assembled line. After applying a patch, clicking Save will allow you to save this patch directly to the ROM file.

              -


              -


              -

              Other

              -


              -

              If the ".DEB files" checkbox in the lower right corner of the debugger window is checked, the emulator will automatically save debug settings such as breakpoints and bookmarks in a .deb file alongside the NES ROM, and load these settings next time you open the ROM.

              -


              -

              There is a "Rom Patcher" button that may be used to apply a small patch to a ROM, although Hex Editor is more convenient in general.

              -


              -

              The "ROM offsets" option will display ROM offsets instead of CPU addresses in the Disassembly window.

              -


              -

              The "Restore Original Window Size" button will restore the original size of the debugger window if you resized it manually.

              -


              -

              The "Auto-open" checkbox causes the debugger window to open automatically whenever an NES ROM is opened.

              -


              -


              -


              -


              -


              +


              +

              The parser is very strict. All numbers are hexadecimal. Always prefix a number with # for an immediate value, or $ for a memory address. If a memory address needs to be calculated use $[] with the calculation inside the brackets.

              +


              +

              Registers A/X/Y are 8-bit unsigned values. Register P is the 16-bit program counter.

              +

              Flags evaluate to 1 if set, 0 if clear.

              +


              +

              Connecting operators || or && combine boolean terms. Parentheses dictate order of operations.

              +


              +

              Example conditions:

              +


              +

              Break only if register A is less than value at memory address $0005:

              +

              A < $0005

              +


              +

              Break only if the value at the indirect address is not equal to FF:

              +

              #FF != $[$10+($11*#100)]

              +


              +

              Break only if flag N is clear or A is not equal to 00:

              +

              (N==#0 || A!=#0)

              +


              +

              Break only when accessing a data from bank 2 (the condiition is relevant when using with Read/Write-type breakpoints):

              +

              T==#2

              +


              +


              +

              Bookmarks

              +


              +

              A list of bookmarked addresses can be kept in the Address Bookmarks frame to make memory navigation easier. Simply type a hexadecimal address (or a convenient string, such as "NMI") and click "Add" to add it to your bookmarks. Alternatively, just left-click any address in the Disassembly window, and the address will appear in the Bookmark Add field, so you don't have to type it.

              +

              Next time you wish to go to this address just double click on the bookmark.

              +

              You can also name bookmarks.

              +

              When you exit the emulator, bookmarks are saved in a .deb file named after the ROM of the debugged game. Next time you return to debugging the game, the list of bookmarks will be automatically loaded from the file.

              +


              +


              +

              Inline Assembler

              +


              +

              Open the inline assembler by left-clicking in the empty column to the left of the memory view.

              +


              +

              The starting memory address is displayed in the PC field at the top of the inline assembler window. Type a line of assembly to add in the empty field just below this, and hit enter. The assembled code of your patch will appear below as you enter each line.

              +


              +

              Click Apply to apply your patch to the ROM in memory. Click Undo to remove the last assembled line. After applying a patch, clicking Save will allow you to save this patch directly to the ROM file.

              +


              +


              +

              Other

              +


              +

              If the ".DEB files" checkbox in the lower right corner of the debugger window is checked, the emulator will automatically save debug settings such as breakpoints and bookmarks in a .deb file alongside the NES ROM, and load these settings next time you open the ROM.

              +


              +

              There is a "Rom Patcher" button that may be used to apply a small patch to a ROM, although Hex Editor is more convenient in general.

              +


              +

              The "ROM offsets" option will display ROM offsets instead of CPU addresses in the Disassembly window.

              +


              +

              The "Restore Original Window Size" button will restore the original size of the debugger window if you resized it manually.

              +


              +

              The "Auto-open" checkbox causes the debugger window to open automatically whenever an NES ROM is opened.

              +


              +


              +


              +


              +


              -

              Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

              -
- - + + +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + - -
- - diff --git a/web/help/Directories.html b/web/help/Directories.html index fad7c6cf..13e23c09 100644 --- a/web/help/Directories.html +++ b/web/help/Directories.html @@ -1,126 +1,317 @@ - - + + + + + - Directories - - - - - - - - - - + + + + + + + + Directories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Directories

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Directory Overrides

-


-


-

This menu sets a default directory override for various files relating to FCEU.

-


-

Base Directory

-

sets the default directory FCEU will use.  It will be the folder that FCEU creates all the sub folders (unless they are also overridden).

-


-


-

ROMS

-

where FCEU will look for ROMS by default.  (What folder will appear when selecting the Files > Open...)

-


-


-

Battery Saves

-

where .sav files will stored and opened from.  These files contain the battery backed SRAM used in some games (such as Dragon Warrior).

-


-


-

Save States

-

where .fcs (savestate) files will be stored.

-


-


-

FDS BIOS ROM

-

where FCEU can find disksys.rom.  disksys.rom is a required file in order to load FDS (Famicom Disk System) games.  If not specified, FCEUX will default to the base directory.

-


-


-

Screenshots

-

where screen captures (.png) files will be saved.

-


-


-

Save Screenshots as "<filebase>-<x>.png"

-

sets how the .png files will be named.  Left unchecked, the file names will simply be 0.png, 1.png etc.  Checked adds the ROM name into the file as well (such as Double Dragon 2 (U)-0.png)

-


-


-

Cheats

-

where .cht files will be stored.  .cht files store the active cheats set up in Cheat Search.

-


-


-

Movies

-

where  .fm2 files will be saved/loaded.  These files are the input files used in movie recording.

-


-


-

Memory Watch

-

where memory watch files are saved/loaded.  These are used by memory watch.

-


-


-

Input Presets

-

where input presets will be saved/loaded.  These are used in the presets section on the input config window.

-


-


-

Lua Scripts

-

where Lua scripts will be saved/loaded.  These are used when using the Lua Scripting tool.

-


-


-

AVI Output

-

overrides which directory FCEUX will default to when saving a .avi file.

-

-

Created with the Personal Edition of HelpNDoc: Free EPub producer

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Directories

+ +
+ +

+

Directory Overrides

+


+


+

This menu sets a default directory override for various files relating to FCEU.

+


+

Base Directory

+

sets the default directory FCEU will use.  It will be the folder that FCEU creates all the sub folders (unless they are also overridden).

+


+


+

ROMS

+

where FCEU will look for ROMS by default.  (What folder will appear when selecting the Files > Open...)

+


+


+

Battery Saves

+

where .sav files will stored and opened from.  These files contain the battery backed SRAM used in some games (such as Dragon Warrior).

+


+


+

Save States

+

where .fcs (savestate) files will be stored. 

+


+


+

FDS BIOS ROM

+

where FCEU can find disksys.rom.  disksys.rom is a required file in order to load FDS (Famicom Disk System) games.  If not specified, FCEUX will default to the base directory.

+


+


+

Screenshots

+

where screen captures (.png) files will be saved.

+


+


+

Save Screenshots as "<filebase>-<x>.png"

+

sets how the .png files will be named.  Left unchecked, the file names will simply be 0.png, 1.png etc.  Checked adds the ROM name into the file as well (such as Double Dragon 2 (U)-0.png)

+


+


+

Cheats

+

where .cht files will be stored.  .cht files store the active cheats set up in Cheat Search.

+


+


+

Movies

+

where  .fm2 files will be saved/loaded.  These files are the input files used in movie recording.

+


+


+

Memory Watch

+

where memory watch files are saved/loaded.  These are used by memory watch.

+


+


+

Input Presets

+

where input presets will be saved/loaded.  These are used in the presets section on the input config window.

+


+


+

Lua Scripts

+

where Lua scripts will be saved/loaded.  These are used when using the Lua Scripting tool.

+


+


+

AVI Output

+

overrides which directory FCEUX will default to when saving a .avi file.

+

+

Created with the Personal Edition of HelpNDoc: Produce electronic books easily

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/FAQGuides.html b/web/help/FAQGuides.html index fee96374..124e24c3 100644 --- a/web/help/FAQGuides.html +++ b/web/help/FAQGuides.html @@ -1,92 +1,287 @@ - - + + + + + - FAQ / Guides - - - - - - - - - - + + + + + + + + FAQ / Guides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

FAQ / Guides

- -
-
- Previous - - Next - -
-
-
-
- -

-

FAQ / Guides

-


-

Information regarding various concepts such as TAS, ROM Hacking, RAM Mapping.

-


-

Troubleshooting FAQ

-


-

A guide to common problems people experience, and what to do about them.

-


-


-

Tool Assisted Speedruns (TAS)

-


-

Information regarding Tool Assisted Speedruns and the TAS community.

-


-


-

ROM Hacking

-


-

Information regarding making ROM Hacks and the ROM Hacking community.

-


-


-

NES RAM Mapping

-


-

A guide to the layout of NES RAM, and how to interpret its contents.

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

FAQ / Guides

+ +
+ +

+

FAQ / Guides

+


+

Information regarding various concepts such as TAS, ROM Hacking, RAM Mapping.

+


+

Troubleshooting FAQ

+


+

A guide to common problems people experience, and what to do about them.

+


+


+

Tool Assisted Speedruns (TAS)

+


+

Information regarding Tool Assisted Speedruns and the TAS community.

+


+


+

ROM Hacking

+


+

Information regarding making ROM Hacks and the ROM Hacking community.

+


+


+

NES RAM Mapping

+


+

A guide to the layout of NES RAM, and how to interpret its contents.

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Produce online help for Qt applications

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/FCEUltraVersionHistory.html b/web/help/FCEUltraVersionHistory.html index 6b31de52..0a91b618 100644 --- a/web/help/FCEUltraVersionHistory.html +++ b/web/help/FCEUltraVersionHistory.html @@ -1,149 +1,340 @@ - - + + + + + - FCE Ultra Version History - - - - - - - - - - + + + + + + + + FCE Ultra Version History + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

FCE Ultra Version History

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

History of FCEUX / FCE Ultra

-


-

FCEUX was started in 2006 by zeromus and rheiny (sp) as an attempt to merge various branches of FCE Ultra into a unified emulator.  Additional authors joined the project, including mz, adelikat, nitsujrehtona, maximus, CaH4e3, qFox, punkrockguy318, Sebastian Porst, AnS, feos, and rainwarrior.

-


-

FCEUX contains all features and enhancements from FCE, FCE Ultra, FCEU rerecording, FCEUXD, and FCEUXDSP as well as many new mappers from FCEU-mm.

-


-

FCEUX sourceforge page

-


-


-

Version Releases

-


-

Look at the Side Bar navigation for changelog information on FCEUX 2.1 and newer.

-


-

FCEUX 2.0.3 - Released November 02, 2008 (see changelog)

-


-

FCEUX 2.0.2 - Released August 14, 2008 (see changelog)

-


-

FCEUX 2.0.1 - Released August 04, 2008 (see changelog)

-


-

FCEUX 2.0.0 - Released August 02, 2008 (see changelog)

-


-

FCE / FCEUltra

-


-

Bero originally wrote a Nintendo Entertainment System/Famicom emulator that was referred to as FCE. This name was apparently meant only to serve as a temporary name, but its usage remained. Xodnizel originally ported it to Linux SVGAlib, and made a few improvements. This code base was abandoned, and work began anew, under DOS, with the original FCE source code. At the end of November, 1998, FCE Ultra Beta 1 was released.

-


-

FCE Ultra remained DOS-only until version 0.18, when it was ported to Linux SVGAlib, and released as a statically-linked executable. The first MS Windows port was released as version 0.25.

-


-

The source code of 0.40 was released on November 12, 2000. It retained the simple license of FCE for a long time, which stated that "This software is freeware. You can use it non-commercially." Almost two years later, in June 2002, 0.80 was released, and FCE Ultra was re-licensed under the GNU GPL.

-


-

It has been tested (and runs) under DOS, Linux SVGAlib, Linux X, Mac OS X, and Windows. A native GUI is provided for the Windows port, and the other ports use a command-line interface. The SDL port should run on any modern UNIX-like operating system (such as FreeBSD, Solaris or IRIX) with no code changes. It has also been ported to the GP2X, PlayStation Portable as PSPFceUltra, the Nintendo GameCube and Pepper Pad.

-


-

FCE Ultra was created by Xodnizel. Development appeared to stop and the homepage and forums for the emulator were taken down. The last version before this was v0.98.13-pre, released in September 2004 as source-only. The last binary release was v0.98.12 in August 2004.

-


-

However, it was resurrected again in March of 2006 by Anthony Giorgio and Mark Doliner.

-


-

There is also a graphical frontend for FCE Ultra. GFCE Ultra is written in Python and uses the GTK2 user interface library. Because is it written in Python and with portability in mind, it can be run on any UNIX-like platform and any processor architecture that is supported by Python.

-


-


-

FCEU Rerecording

-


-

The "rerecording" version of FCE Ultra was implemented to FCE Ultra 0.98.10 with movie recording support.  This was done by blip, and was implemented for the purpose of creating Tool-Assisted Speedruns.

-


-

The rerecording branch continued with 0.98.12, adding movie support features, such as "bullet proof" recording.  In 2006, FCEU 0.98.16 was implemented by nitsuja and luke.  Various tools such as read-only toggling, increased hotkey mapping, and memory watch were added.

-


-

In 2008, FCEU rerecording was picked up again by mz, maximus, adelikat, and nitsujrehtona with various updates named FCEU.0.98.17 - 0.98.28

-


-

FCEU.28 GoogleCode Page

-


-


-

FCEUD / FCEUXD / FCEUXDSP / FCEUXDSP CE

-


-

FCEUD

-

In 2002, Parasyte modified the then-current version (0.81.3) of FCE Ultra and added a Nesten-style debugger, along with several other features, and named it "FCEUD" (FCE Ultra Debugger).

-


-

FCEUXD

-

In January 2004, bbitmaster began working on more features and called it "FCEUXD" (FCE Ultra Extended Debugger).

-

It is a branch of FCE Ultra that contains many extended debugging features compared to the original FCE Ultra code such as a trace logger, a built-in hex editor, a name table viewer, code/data logger, inline assembler, and Game Genie decoder/encoder in addition to the debugger and PPU viewer from FCEUD.  The last version made was FCEUXD 1.0a.

-


-

FCEUXDSP

-

FCEUXDSP stands for FCEUXD "SP" version and is a branch of FCEUXD 1.0a.

-

It was created in 2006 by sp.  The project extends the debugging tools even further compared to FCEUXD by adding new tools, functions, and usability of debugging tools.  

-


-

The last version of FCEUXDSP was 1.07 which adds a feature known as the RAM Filter. This has since been removed, due to functional redundancy.

-


-

FCEUXDSP homepage

-


-

FCEUXDSP CE

-

CE stands for "Champion Edition" and is a branch of XDSP that adds a text hooker tool.

-


-

FCEUXDSP CE homepage

-


-

FCEU-mm

-


-

FCEU "mappers modified" is an unofficial build of FCEU Ultra by CaH4e3, which supports a lot of new mappers including some obscure mappers such as one for unlicensed NES ROM's.

-


-

FCEUX supports mappers from older versions of FCEU-mm.

-


-

FCEU-mm SourceForge page

-

-

Created with the Personal Edition of HelpNDoc: Easily create CHM Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

FCE Ultra Version History

+ +
+ +

+

History of FCEUX / FCE Ultra

+


+

FCEUX was started in 2006 by zeromus and rheiny (sp) as an attempt to merge various branches of FCE Ultra into a unified emulator.  Additional authors joined the project, including mz, adelikat, nitsujrehtona, maximus, CaH4e3, qFox, punkrockguy318, Sebastian Porst, AnS, feos, and rainwarrior.

+


+

FCEUX contains all features and enhancements from FCE, FCE Ultra, FCEU rerecording, FCEUXD, and FCEUXDSP as well as many new mappers from FCEU-mm.

+


+

FCEUX sourceforge page

+


+


+

Version Releases

+


+

Look at the Side Bar navigation for changelog information on FCEUX 2.1 and newer.

+


+

FCEUX 2.0.3 - Released November 02, 2008 (see changelog)

+


+

FCEUX 2.0.2 - Released August 14, 2008 (see changelog)

+


+

FCEUX 2.0.1 - Released August 04, 2008 (see changelog)

+


+

FCEUX 2.0.0 - Released August 02, 2008 (see changelog)

+


+

FCE / FCEUltra

+


+

Bero originally wrote a Nintendo Entertainment System/Famicom emulator that was referred to as FCE. This name was apparently meant only to serve as a temporary name, but its usage remained. Xodnizel originally ported it to Linux SVGAlib, and made a few improvements. This code base was abandoned, and work began anew, under DOS, with the original FCE source code. At the end of November, 1998, FCE Ultra Beta 1 was released.

+


+

FCE Ultra remained DOS-only until version 0.18, when it was ported to Linux SVGAlib, and released as a statically-linked executable. The first MS Windows port was released as version 0.25.

+


+

The source code of 0.40 was released on November 12, 2000. It retained the simple license of FCE for a long time, which stated that "This software is freeware. You can use it non-commercially." Almost two years later, in June 2002, 0.80 was released, and FCE Ultra was re-licensed under the GNU GPL. 

+


+

It has been tested (and runs) under DOS, Linux SVGAlib, Linux X, Mac OS X, and Windows. A native GUI is provided for the Windows port, and the other ports use a command-line interface. The SDL port should run on any modern UNIX-like operating system (such as FreeBSD, Solaris or IRIX) with no code changes. It has also been ported to the GP2X, PlayStation Portable as PSPFceUltra, the Nintendo GameCube and Pepper Pad.

+


+

FCE Ultra was created by Xodnizel. Development appeared to stop and the homepage and forums for the emulator were taken down. The last version before this was v0.98.13-pre, released in September 2004 as source-only. The last binary release was v0.98.12 in August 2004.

+


+

However, it was resurrected again in March of 2006 by Anthony Giorgio and Mark Doliner.

+


+

There is also a graphical frontend for FCE Ultra. GFCE Ultra is written in Python and uses the GTK2 user interface library. Because is it written in Python and with portability in mind, it can be run on any UNIX-like platform and any processor architecture that is supported by Python.

+


+


+

FCEU Rerecording

+


+

The "rerecording" version of FCE Ultra was implemented to FCE Ultra 0.98.10 with movie recording support.  This was done by blip, and was implemented for the purpose of creating Tool-Assisted Speedruns.

+


+

The rerecording branch continued with 0.98.12, adding movie support features, such as "bullet proof" recording.  In 2006, FCEU 0.98.16 was implemented by nitsuja and luke.  Various tools such as read-only toggling, increased hotkey mapping, and memory watch were added.

+


+

In 2008, FCEU rerecording was picked up again by mz, maximus, adelikat, and nitsujrehtona with various updates named FCEU.0.98.17 - 0.98.28

+


+

FCEU.28 GoogleCode Page

+


+


+

FCEUD / FCEUXD / FCEUXDSP / FCEUXDSP CE

+


+

FCEUD

+

In 2002, Parasyte modified the then-current version (0.81.3) of FCE Ultra and added a Nesten-style debugger, along with several other features, and named it "FCEUD" (FCE Ultra Debugger).

+


+

FCEUXD

+

In January 2004, bbitmaster began working on more features and called it "FCEUXD" (FCE Ultra Extended Debugger).

+

It is a branch of FCE Ultra that contains many extended debugging features compared to the original FCE Ultra code such as a trace logger, a built-in hex editor, a name table viewer, code/data logger, inline assembler, and Game Genie decoder/encoder in addition to the debugger and PPU viewer from FCEUD.  The last version made was FCEUXD 1.0a.

+


+

FCEUXDSP

+

FCEUXDSP stands for FCEUXD "SP" version and is a branch of FCEUXD 1.0a.

+

It was created in 2006 by sp.  The project extends the debugging tools even further compared to FCEUXD by adding new tools, functions, and usability of debugging tools.  

+


+

The last version of FCEUXDSP was 1.07 which adds a feature known as the RAM Filter. This has since been removed, due to functional redundancy.

+


+

FCEUXDSP homepage

+


+

FCEUXDSP CE

+

CE stands for "Champion Edition" and is a branch of XDSP that adds a text hooker tool.

+


+

FCEUXDSP CE homepage

+


+

FCEU-mm

+


+

FCEU "mappers modified" is an unofficial build of FCEU Ultra by CaH4e3, which supports a lot of new mappers including some obscure mappers such as one for unlicensed NES ROM's.

+


+

FCEUX supports mappers from older versions of FCEU-mm.

+


+

FCEU-mm SourceForge page

+

+

Created with the Personal Edition of HelpNDoc: Free help authoring tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/GUI.html b/web/help/GUI.html index 2517e362..3fa0c707 100644 --- a/web/help/GUI.html +++ b/web/help/GUI.html @@ -1,120 +1,311 @@ - - + + + + + - GUI - - - - - - - - - - + + + + + + + + GUI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

GUI

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

GUI

-


-

Various toggle boxes related to the FCEUX main window.

-


-


-

Load "File Open" dialog when FCEUX starts.

-


-

If enabled, FCEUX will ask for a ROM to open upon FCEUX start up.

-


-


-

Automatically hide menu on game load.

-


-

If enabled, the FCEU Menu will be hidden while a ROM is loaded.  To unhide it, press the ESC key.

-


-


-

Ask confirmation on exit attempt.

-


-

If enabled, FCEUX will ask you before closing the window.  (It may also say some other things...)

-


-


-

Disable screen saver while game is loaded.

-


-

This is enabled by default.  If a game is running, the windows screen saver will not turn on.

-


-


-

Enable right-click context menu.

-


-

This is enabled by default.  This allows you to right-click on the emulator to get context menus.  The context menu gives many common options for a given situation and has a few options not available otherwise.

-


-


-

Switch fullscreen by double-click

-


-

If enabled, you may switch between fullscreen mode and windowed mode by a double-click on the emulator.

-


-


-

Partially disable Visual Themes (Requires restart)

-


-

If enabled, dialog windows in FCEUX will use classic Visual Theme (a la Windows98 interface).

-


-


-

Single Instance Mode

-


-

If enabled, starting a second copy of FCEUX with a path to a game will make FCEUX load the file into the first window, then exit. This will ensure that only one instance of FCEUX is running in your OS.

-


-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

GUI

+ +
+ +

+

GUI

+


+

Various toggle boxes related to the FCEUX main window.

+


+


+

Load "File Open" dialog when FCEUX starts.

+


+

If enabled, FCEUX will ask for a ROM to open upon FCEUX start up. 

+


+


+

Automatically hide menu on game load.

+


+

If enabled, the FCEU Menu will be hidden while a ROM is loaded.  To unhide it, press the ESC key.

+


+


+

Ask confirmation on exit attempt.

+


+

If enabled, FCEUX will ask you before closing the window.  (It may also say some other things...)

+


+


+

Disable screen saver while game is loaded. 

+


+

This is enabled by default.  If a game is running, the windows screen saver will not turn on.

+


+


+

Enable right-click context menu.

+


+

This is enabled by default.  This allows you to right-click on the emulator to get context menus.  The context menu gives many common options for a given situation and has a few options not available otherwise.

+


+


+

Switch fullscreen by double-click

+


+

If enabled, you may switch between fullscreen mode and windowed mode by a double-click on the emulator.

+


+


+

Partially disable Visual Themes (Requires restart)

+


+

If enabled, dialog windows in FCEUX will use classic Visual Theme (a la Windows98 interface).

+


+


+

Single Instance Mode

+


+

If enabled, starting a second copy of FCEUX with a path to a game will make FCEUX load the file into the first window, then exit. This will ensure that only one instance of FCEUX is running in your OS.

+


+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free EPub producer

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/GameGenieEncoderDecoder.html b/web/help/GameGenieEncoderDecoder.html index baa14de8..a935ce9e 100644 --- a/web/help/GameGenieEncoderDecoder.html +++ b/web/help/GameGenieEncoderDecoder.html @@ -1,104 +1,295 @@ - - + + + + + - Game Genie Encoder/Decoder - - - - - - - - - - + + + + + + + + Game Genie Encoder/Decoder + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Game Genie Encoder/Decoder

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Game Genie Decoder/Encoder

-


-

This will take an NES address space PRG address ($8000-$FFFF), a comparison value (for 8-letter GG codes; refer to a Game Genie code FAQ for an explanation of what this does), and a Value that replaces the addressed byte.

-


-

Filling in the Address and Value fields will produce a 6-letter code; if you also fill out the Compare field, it will produce an 8-letter code.  The code so produced will appear in the Game Genie Code box immediately; you can then click "Add to Cheat List" to activate it.

-


-

To decrypt a Game Genie code, enter it into the Game Genie Code box, and the Address and Value fields will be automatically filled in, as will the Compare field if it was an 8-letter code.

-


-

Adding Game Genie codes

-


-

In the Game Genie Code Decoder/Encoder window, type the code into the Game Genie Code box and click "Add to Cheat List", which will add it to the Cheat Search cheat list. You can then enable/disable them by double-clicking the code in the box (a * means the code is active).

-


-


-

Making Game Genie codes permanent

-


-

Using the Game Genie Code Decoder/Encoder, enter in your code in the "Game Genie Code" box, and under "Possible Affected ROM File Addresses", a list of possible matches (usually from 1 to 5) is displayed. Using the built-in Hex Editor, go to the first listed address in the ROM, and change its value to the value given in the "Value" box (of the GG code Decoder/Encoder window). If the desired effect isn't achieved, undo the change (Ctrl+Z) and try the next address. Repeat until the desired effect is achieved, and then save the ROM.

-


-


-

How do I make my own Game Genie codes?

-


-

First of all, you must:

-


-

* have a decent amount of ASM knowledge;

-

* know how to use the debugger;

-

* understand NES PRG-ROM bank switching.

-


-

Once you've found a part of PRG-ROM you want to change to create a code effect, snap the Debugger (if it's not so already) and find the code's location in the PRG-ROM's address space ($8000-$FFFF) (you'll want the debugger snapped so the game won't swap banks out from under you). Then, using the built-in Hex Editor, view the NES memory and go to the PRG-ROM address you wish to modify, then right-click the byte and choose "Create Game Genie Code at this Address". The Game Genie Code Decoder/Encoder will appear, with the Address and Compare boxes filled in (the Compare box represents the address's original value). Enter the new value into the "Value" box.

-


-

An alternative way to enter the code is to locate the desired address in the debugger, and then middle-click on it, which will summon the GG Code Decoder/Encoder. Then enter the code as described above.

-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free EPub and documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Game Genie Encoder/Decoder

+ +
+ +

+

Game Genie Decoder/Encoder

+


+

This will take an NES address space PRG address ($8000-$FFFF), a comparison value (for 8-letter GG codes; refer to a Game Genie code FAQ for an explanation of what this does), and a Value that replaces the addressed byte.

+


+

Filling in the Address and Value fields will produce a 6-letter code; if you also fill out the Compare field, it will produce an 8-letter code.  The code so produced will appear in the Game Genie Code box immediately; you can then click "Add to Cheat List" to activate it.

+


+

To decrypt a Game Genie code, enter it into the Game Genie Code box, and the Address and Value fields will be automatically filled in, as will the Compare field if it was an 8-letter code.

+


+

Adding Game Genie codes

+


+

In the Game Genie Code Decoder/Encoder window, type the code into the Game Genie Code box and click "Add to Cheat List", which will add it to the Cheat Search cheat list. You can then enable/disable them by double-clicking the code in the box (a * means the code is active).

+


+


+

Making Game Genie codes permanent

+


+

Using the Game Genie Code Decoder/Encoder, enter in your code in the "Game Genie Code" box, and under "Possible Affected ROM File Addresses", a list of possible matches (usually from 1 to 5) is displayed. Using the built-in Hex Editor, go to the first listed address in the ROM, and change its value to the value given in the "Value" box (of the GG code Decoder/Encoder window). If the desired effect isn't achieved, undo the change (Ctrl+Z) and try the next address. Repeat until the desired effect is achieved, and then save the ROM.

+


+


+

How do I make my own Game Genie codes?

+


+

First of all, you must:

+


+

* have a decent amount of ASM knowledge;

+

* know how to use the debugger;

+

* understand NES PRG-ROM bank switching.

+


+

Once you've found a part of PRG-ROM you want to change to create a code effect, snap the Debugger (if it's not so already) and find the code's location in the PRG-ROM's address space ($8000-$FFFF) (you'll want the debugger snapped so the game won't swap banks out from under you). Then, using the built-in Hex Editor, view the NES memory and go to the PRG-ROM address you wish to modify, then right-click the byte and choose "Create Game Genie Code at this Address". The Game Genie Code Decoder/Encoder will appear, with the Address and Compare boxes filled in (the Compare box represents the address's original value). Enter the new value into the "Value" box. 

+


+

An alternative way to enter the code is to locate the desired address in the debugger, and then middle-click on it, which will summon the GG Code Decoder/Encoder. Then enter the code as described above.

+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured Kindle eBooks generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Gamefilecompatibility.html b/web/help/Gamefilecompatibility.html index 2112c569..a5df5589 100644 --- a/web/help/Gamefilecompatibility.html +++ b/web/help/Gamefilecompatibility.html @@ -1,100 +1,291 @@ - - + + + + + - Game file compatibility - - - - - - - - - - + + + + + + + + Game file compatibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Game file compatibility

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

File Formats/Expansion Hardware

-


-

Valid Game Types

-


-

FCEUX supports the iNES, FDS(raw and with a header), UNIF, and NSF file formats. FDS ROM images in the iNES format are not supported; it would be silly to do so and storing them in that format is nonsensical.

-


-

FCEUX supports loading ROM/disk images from some types of compressed files. FCEUX can load data from both PKZIP-format files and gzip-format files. Only the "deflate" algorithm is supported, but this is the most widely used algorithm for these formats.

-


-

Playing from compressed (.zip) files

-


-

FCEUX is compatible with all compression types compatible with 7z.  Compatible types include .7z, .zip, .rar, and .tar.

-


-

If an archive file is opened, it will be scanned for the followings extensions: .nes, .fds, .nsf, .unf, .nez, .unif.  If more than one valid type is detected, a dialog box will open up with a list of available choices.

-


-

Automatic IPS Patching (Playing Hacked Games)

-


-

FCEUX supports automatic IPS patching.  

-


-

Place the IPS file in the same directory as the file to load, and name it [filename.extension].ips.

-


-

       Examples:        Boat.nes -      Boat.nes.ips

-

                       Boat.zip -       Boat.zip.ips

-

                       Boat.nes.gz -  Boat.nes.gz.ips

-

                       Boat     -         Boat.ips

-

       

-


-

(Some operating systems and environments will hide file extensions. Keep this in mind if you are having trouble.)

-


-

Patching is supported for all supported formats (iNES, FDS, UNIF, and NSF), but it will probably only be useful for the iNES and FDS formats. UNIF files can't be patched well with the IPS format because they are chunk-based with no fixed offsets.

-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Game file compatibility

+ +
+ +

+

File Formats/Expansion Hardware

+


+

Valid Game Types

+


+

FCEUX supports the iNES, FDS(raw and with a header), UNIF, and NSF file formats. FDS ROM images in the iNES format are not supported; it would be silly to do so and storing them in that format is nonsensical.

+


+

FCEUX supports loading ROM/disk images from some types of compressed files. FCEUX can load data from both PKZIP-format files and gzip-format files. Only the "deflate" algorithm is supported, but this is the most widely used algorithm for these formats.

+


+

Playing from compressed (.zip) files

+


+

FCEUX is compatible with all compression types compatible with 7z.  Compatible types include .7z, .zip, .rar, and .tar.

+


+

If an archive file is opened, it will be scanned for the followings extensions: .nes, .fds, .nsf, .unf, .nez, .unif.  If more than one valid type is detected, a dialog box will open up with a list of available choices.

+


+

Automatic IPS Patching (Playing Hacked Games)

+


+

FCEUX supports automatic IPS patching.  

+


+

Place the IPS file in the same directory as the file to load, and name it [filename.extension].ips.

+


+

        Examples:        Boat.nes -      Boat.nes.ips

+

                        Boat.zip -       Boat.zip.ips

+

                        Boat.nes.gz -  Boat.nes.gz.ips

+

                        Boat     -         Boat.ips

+

        

+


+

(Some operating systems and environments will hide file extensions. Keep this in mind if you are having trouble.)

+


+

Patching is supported for all supported formats (iNES, FDS, UNIF, and NSF), but it will probably only be useful for the iNES and FDS formats. UNIF files can't be patched well with the IPS format because they are chunk-based with no fixed offsets. 

+

+

Created with the Personal Edition of HelpNDoc: Easy EBook and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/General.html b/web/help/General.html index c0ff4d31..3a0bacf5 100644 --- a/web/help/General.html +++ b/web/help/General.html @@ -1,94 +1,289 @@ - - + + + + + - General - - - - - - - - - - + + + + + + + + General + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

General

- -
-
- Previous - - Next - -
-
-
-
- -

-

General

-


-

Guides for general uses of FCEUX.

-


-

Getting Started

-


-

A guide for loading games, setting up controls, etc.

-


-


-

Command Line Options

-


-

FCEUX as an extensive set of options for running from command line (or .bat file).  This guide explains all command options available.

-


-


-

Famicom Disk System

-


-

A guide for playing Famicom Disk System (.fds) games.

-


-


-

Movie Recording

-


-

A guide for playing and recording movie input files (.fm2).

-


-


-

AVI Capturing

-


-

A guide for capturing a game/movie file into an AVI file.

-

-

Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

General

+ +
+ +

+

General

+


+

Guides for general uses of FCEUX.

+


+

Getting Started

+


+

A guide for loading games, setting up controls, etc.

+


+


+

Command Line Options

+


+

FCEUX as an extensive set of options for running from command line (or .bat file).  This guide explains all command options available.

+


+


+

Famicom Disk System

+


+

A guide for playing Famicom Disk System (.fds) games.

+


+


+

Movie Recording

+


+

A guide for playing and recording movie input files (.fm2).

+


+


+

AVI Capturing

+


+

A guide for capturing a game/movie file into an AVI file.

+

+

Created with the Personal Edition of HelpNDoc: Generate Kindle eBooks with ease

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Gettingstarted.html b/web/help/Gettingstarted.html index bb09df83..529377f1 100644 --- a/web/help/Gettingstarted.html +++ b/web/help/Gettingstarted.html @@ -1,110 +1,301 @@ - - + + + + + - Getting Started - - - - - - - - - - + + + + + + + + Getting Started + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Getting Started

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Getting Started

-


-

Playing Games

-


-

The most basic function of FCEUX is to play Nintendo Entertainment System (NES) and Famicom Disk System (FDS) games.

-


-

To play a game, simply open a ROM by selecting "Open" in the File Menu (or press Ctrl+O).  (See Game Compatibility for information regarding file types that are compatible with FCEU.)

-


-

To get set up properly, you may need to configure any of the following:

-


-

-Input

-

-Video

-

-Sound

-

-Timing

-

-GUI settings

-

-Hotkeys

-

-Directory Overrides

-


-


-

Using Savestates

-


-

In emulation, a savestate (alternatively called freeze state or game freeze) is a snapshot of all of an emulated device's state information at a given moment. This makes it possible to pause emulation, and restart it later, even in another instance of the emulator, or to test the emulated machines reaction to different series of inputs using the saved state as a common starting point.

-


-

To make a savestate press shift + F1-F10 to save to a save slot (0-9).  Or select a save slot with the number keys (0-9) and select the quick save command (Default hotkey is "I")

-


-

To load a savestate press F1-F10.  Or select a save slot with the number keys (0-9) and loadstate by navigating to File > Savestate >  Loadstate or by pressing the loadstate hotkey (Default hotkey is "P").

-


-

To save a state to a specific file, go to "Save state as..." in the FCEUX File menu.

-


-

To load a specific savestate file, go to the "Load state from..." in the FCEUX File menu.

-


-


-

Undo Savestate / Loadstate

-


-

If you load a state by accident, you can right-click and select "Undo Loadstate" to restore the emulator back to the state it was in before the loadstate.  Upon using undo loadstate, a redo loadstate will appear as an option.  

-


-

If you make a savestate, it will overwrite the existing savestate for that slot.  You have the option to undo this and restore the previous savestate file by right-clicking and selecting undo savestate.  Once you undo, you will have the option to redo savestate to restore the savestate that you made.  You can also map a hotkey to this function, by default it's mapped to Ctrl+Z.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Create iPhone web-based documentation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Getting Started

+ +
+ +

+

Getting Started

+


+

Playing Games

+


+

The most basic function of FCEUX is to play Nintendo Entertainment System (NES) and Famicom Disk System (FDS) games.

+


+

To play a game, simply open a ROM by selecting "Open" in the File Menu (or press Ctrl+O).  (See Game Compatibility for information regarding file types that are compatible with FCEU.)

+


+

To get set up properly, you may need to configure any of the following:

+


+

-Input

+

-Video

+

-Sound

+

-Timing

+

-GUI settings

+

-Hotkeys

+

-Directory Overrides

+


+


+

Using Savestates

+


+

In emulation, a savestate (alternatively called freeze state or game freeze) is a snapshot of all of an emulated device's state information at a given moment. This makes it possible to pause emulation, and restart it later, even in another instance of the emulator, or to test the emulated machines reaction to different series of inputs using the saved state as a common starting point. 

+


+

To make a savestate press shift + F1-F10 to save to a save slot (0-9).  Or select a save slot with the number keys (0-9) and select the quick save command (Default hotkey is "I")

+


+

To load a savestate press F1-F10.  Or select a save slot with the number keys (0-9) and loadstate by navigating to File > Savestate >  Loadstate or by pressing the loadstate hotkey (Default hotkey is "P").

+


+

To save a state to a specific file, go to "Save state as..." in the FCEUX File menu.

+


+

To load a specific savestate file, go to the "Load state from..." in the FCEUX File menu.

+


+


+

Undo Savestate / Loadstate

+


+

If you load a state by accident, you can right-click and select "Undo Loadstate" to restore the emulator back to the state it was in before the loadstate.  Upon using undo loadstate, a redo loadstate will appear as an option.  

+


+

If you make a savestate, it will overwrite the existing savestate for that slot.  You have the option to undo this and restore the previous savestate file by right-clicking and selecting undo savestate.  Once you undo, you will have the option to redo savestate to restore the savestate that you made.  You can also map a hotkey to this function, by default it's mapped to Ctrl+Z.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Qt Help documentation made easy

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/HexEditor.html b/web/help/HexEditor.html index 7ba87969..173b536c 100644 --- a/web/help/HexEditor.html +++ b/web/help/HexEditor.html @@ -1,131 +1,319 @@ - - + + + + + - Hex Editor - - - - - - - - - - + + + + + + + + Hex Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Hex Editor

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Hex Editor

-


-


-

The Hex Editor is a very powerful memory viewing/editing tool, it obsoletes the Memory Viewer tool from the FCE Ultra and FCEU Rerecording branches.

-


-

It can do a wide range of things.  It allows you to view the entire RAM & ROM contents in a resizable dialog window. It makes it easy to edit the game's RAM, PPU memory, and even its currently-loaded ROM data by simply typing in values in the editor. You can also "freeze" parts of RAM (to prevent the game from modifying the data there), search for data (Ctrl+F), and even copy and paste data to/from the clipboard.  Furthermore, table files are supported, so you can edit a game's text in real-time and see the result immediately.

-


-

Basically, it lets you tinker with any part of a game's RAM or ROM while it is running.

-


-

Using the Hex Editor

-


-

The Hex Editor lets you edit three major areas:

-


-

1. NES MEMORY

-

This allows you to directly edit all of the NES address space (System Bus - $0000-$FFFF). While you can easily modify RAM, or write directly to registers by typing in data, you cannot modify ROM data ($8000-$FFFF) itself. This is because most mappers have registers which are located in this space; so writing there can trigger mapper operations that may cause the game to crash or glitch if you don't know what you're doing.  If you want to edit the ROM itself, right-click on the offset and select  "Go here in ROM file"; that will take you directly to where you need to be so you can start editing.  You can also freeze RAM by clicking on it with the middle mouse button, or by using the right-click menu. This works by adding it directly to the Cheat List, which you can see from the Cheat Console. Finally, the right-click menu can be used to quickly add a read or write breakpoint to the debugger. When adding a breakpoint to the range of ROM addresses ($8000-$FFFF), the Hex Editor also takes into account the number of the bank in which the byte is located.

-


-

2. PPU MEMORY

-

This allows you to directly view and write to PPU memory (VRAM).

-


-

3. OAM MEMORY

-

This allows you to directly view and write to OAM memory (sprite RAM).

-


-

4. THE ROM FILE

-

This allows you to edit the ROM file in real time, i.e. while the game is running. If you make a mistake, press Ctrl+Z or Edit->Undo to undo your change (then load a save-state if the game crashed).

-


-

The Hex Editor also has support for table files (*.tbl) to map bytes to text. Each line consists of four characters of the form "xx=y", where "xx" is the hex value, and "y" is the character that that value represents. I have also added an extension to represent the Return key:  xx=ret whereby pressing the Return key will enter that value into the ROM.  You can copy/paste data or text by selecting it and using Ctrl+C (to copy) and Ctrl+V (to paste). Plus, there is an Edit->Find feature that you can use to search for data. This feature should be fairly intuitive, so I won't bother to explain it.

-


-

When you're done editing, remember to save the ROM file (File->Save) or your changes will be lost when you close the ROM.

-


-

Why can't I edit NES memory beyond $8000?

-


-

NES memory from $8000-$FFFF is where the game's PRG-ROM code is mapped.  Whenever you type in a value in the NES memory editor, it effectively writes that value to that address. Many games use mappers, which are usually accessed by writing to $8000-$FFFF (which is read-only)... and if *you* were to do so, it may trigger a bankswitch, which could easily make the game crash. In any event, doing so will not modify the ROM itself.  What you *can* do, though, is edit the PRG-ROM itself by right-clicking on the offset you wish to edit, and selecting "Go here in the ROM file", which should take you to that spot in the ROM instead, where you can change the data at instead.

-


-

Highlighting

-


-

The Hex Editor highlights certain bytes with different colors to help you distinguish different data.

-

Usually all bytes are colored black.

-

Bookmarked RAM addresses are highlighted by green color.

-

Freezed RAM addresses are highlighted by blue color.

-

Modified ROM bytes are highlighted by red color.

-

If you have the Code/Data Logger running, bytes that were logged will be colored:

-

For PRG ROM segment:

-

Dark-yellow - the byte is code

-

Blue - the byte is data

-

Cyan - the byte is PCM audio data

-

Green - the byte is both code and data

-

For CHR ROM segment:

-

Yellow - the byte was rendered

-

Light-blue - the byte was read programmatically

-

Light-green - the byte was both rendered and read programmatically

-


-

Highlight Activity

-


-

This feature of the Hex Editor can draw your attention to bytes that changed their value since the last frame, or since the last update of Hex Editor window (if "Fade when paused" option is enabled).

-

If you don't need this feature, you can switch it off in the "Highlighting" submenu.

-

You can customize this feature by changing "fading period".

-

IMPORTANT NOTE: this feature does not track the actual changes of RAM. It works by simply comparing current values to previously displayed values of the same addresses. That's why the feature works with RAM/PPU/OAM/ROM as well.

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Hex Editor

+ +
+ +

+

Hex Editor

+


+


+

The Hex Editor is a very powerful memory viewing/editing tool, it obsoletes the Memory Viewer tool from the FCE Ultra and FCEU Rerecording branches.

+


+

It can do a wide range of things.  It allows you to view the entire RAM & ROM contents in a resizable dialog window. It makes it easy to edit the game's RAM, PPU memory, and even its currently-loaded ROM data by simply typing in values in the editor. You can also "freeze" parts of RAM (to prevent the game from modifying the data there), search for data (Ctrl+F), and even copy and paste data to/from the clipboard.  Furthermore, table files are supported, so you can edit a game's text in real-time and see the result immediately.

+


+

Basically, it lets you tinker with any part of a game's RAM or ROM while it is running.

+


+

Using the Hex Editor

+


+

The Hex Editor lets you edit three major areas:

+


+

1. NES MEMORY

+

This allows you to directly edit all of the NES address space (System Bus - $0000-$FFFF). While you can easily modify RAM, or write directly to registers by typing in data, you cannot modify ROM data ($8000-$FFFF) itself. This is because most mappers have registers which are located in this space; so writing there can trigger mapper operations that may cause the game to crash or glitch if you don't know what you're doing.  If you want to edit the ROM itself, right-click on the offset and select  "Go here in ROM file"; that will take you directly to where you need to be so you can start editing.  You can also freeze RAM by clicking on it with the middle mouse button, or by using the right-click menu. This works by adding it directly to the Cheat List, which you can see from the Cheat Console. Finally, the right-click menu can be used to quickly add a read or write breakpoint to the debugger. When adding a breakpoint to the range of ROM addresses ($8000-$FFFF), the Hex Editor also takes into account the number of the bank in which the byte is located.

+


+

2. PPU MEMORY

+

This allows you to directly view and write to PPU memory (VRAM).

+


+

3. THE ROM FILE

+

This allows you to edit the ROM file in real time, i.e. while the game is running. If you make a mistake, press Ctrl+Z or Edit->Undo to undo your change (then load a save-state if the game crashed).

+


+

The Hex Editor also has support for table files (*.tbl) to map bytes to text. Each line consists of four characters of the form "xx=y", where "xx" is the hex value, and "y" is the character that that value represents. I have also added an extension to represent the Return key:  xx=ret whereby pressing the Return key will enter that value into the ROM.  You can copy/paste data or text by selecting it and using Ctrl+C (to copy) and Ctrl+V (to paste). Plus, there is an Edit->Find feature that you can use to search for data. This feature should be fairly intuitive, so I won't bother to explain it.

+


+

When you're done editing, remember to save the ROM file (File->Save) or your changes will be lost when you close the ROM.

+


+

Why can't I edit NES memory beyond $8000?

+


+

NES memory from $8000-$FFFF is where the game's PRG-ROM code is mapped.  Whenever you type in a value in the NES memory editor, it effectively writes that value to that address. Many games use mappers, which are usually accessed by writing to $8000-$FFFF (which is read-only)... and if *you* were to do so, it may trigger a bankswitch, which could easily make the game crash. In any event, doing so will not modify the ROM itself.  What you *can* do, though, is edit the PRG-ROM itself by right-clicking on the offset you wish to edit, and selecting "Go here in the ROM file", which should take you to that spot in the ROM instead, where you can change the data at instead.

+


+

Highlighting

+


+

The Hex Editor highlights certain bytes with different colors to help you distinguish different data.

+

Usually all bytes are colored black.

+

Bookmarked RAM addresses are highlighted by green color.

+

Freezed RAM addresses are highlighted by blue color.

+

Modified ROM bytes are highlighted by red color.

+

If you have the Code/Data Logger running, bytes that were logged will be colored:

+

For PRG ROM segment:

+

Dark-yellow - the byte is code

+

Blue - the byte is data

+

Cyan - the byte is PCM audio data

+

Green - the byte is both code and data

+

For CHR ROM segment:

+

Yellow - the byte was rendered

+

Light-blue - the byte was read programmatically

+

Light-green - the byte was both rendered and read programmatically

+


+

Highlight Activity

+


+

This feature of the Hex Editor can draw your attention to bytes that changed their value since the last frame, or since the last update of Hex Editor window (if "Fade when paused" option is enabled).

+

If you don't need this feature, you can switch it off in the "Highlighting" submenu.

+

You can customize this feature by changing "fading period".

+

IMPORTANT NOTE: this feature does not track the actual changes of RAM. It works by simply comparing current values to previously displayed values of the same addresses. That's why the feature works with RAM/PPU/ROM as well.

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easy EBook and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Input.html b/web/help/Input.html index 503cea6b..39d2cffa 100644 --- a/web/help/Input.html +++ b/web/help/Input.html @@ -1,123 +1,314 @@ - - + + + + + - Input - - - - - - - - - - + + + + + + + + Input + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Input

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Input Configuration

-


-


-

Setting up controllers

-


-

On the pull down menus, you can select the device you want to be emulated on input ports 1 and 2 (game pad, zapper, pad, paddle). Note: you can't change this setting while a movie is being played or recorded.

-

If you check the box labeled "Attach four-score(implies four gamepads)", you won't be able to select any of these options, because the four-score allows to use 2 extra controllers.

-

The device currently being emulated on each port is listed above the drop down list; loading certain games will override your settings, but only temporarily.

-


-

To bind these controls to specific keys/joystick controls use the  "configure" the device listed above each drop-down list.

-


-

Zapper / Arkanoid Paddle

-


-

Most Zapper NES games expect the Zapper to be plugged into port 2. and most VS Unisystem games expect the Zapper to be plugged into port 1.

-


-

The left mouse button is the emulated trigger button for the Zapper. The right mouse button is also emulated as the trigger, but as long as you have the right mouse button held down, no color detection will take place, which is effectively like pulling the trigger while the Zapper is pointed away from the television screen. Note that you must hold the right button down for a short time to have the desired effect.

-


-

The Arkanoid Paddle emulates the same way the zapper.

-


-

Power Pad A / B

-


-

Emulates the NES Power pad.  The 12 pad buttons can be routed via the configure button.  FCEUX allows up to 2 Power Pads to be emulated at once (Power Pad A and B).

-


-

Famicom Controllers

-


-

You can also select the input device to be emulated on the Famicom Expansion port.  If you select a device for the Famicom Expansion Port, you should probably have emulated game pads on the emulated NES-style input ports.

-


-

In addition to the traditional famicom controller, FCEUX can emulate the Famicom version of the Arkanoid controller, the "Space Shadow" gun, the Famicom 4-player adapter, the Family Keyboard, the HyperShot controller, the Mahjong controller, the Oeka Kids tablet, the Quiz King buzzers, the Family Trainer, and the Barcode World barcode reader.

-


-

Replace Port 2 Start With Microphone

-


-

Checking this box will replace the Start button used by controller 2 with the microphone option found on the famicom. Pressing the Microphone button is like blowing or yelling into it on the console equipment. The Port 2 controller used for the Famicom included a microphone and a volume control in place of the Start and Select buttons. This option isn't automatically detected, so it has to be manually enabled by the user. Movie files may also enable and use this feature. Both Famicom Cartridges and Famicom Disks have made use of this feature, such as both the cartridge and disk version of Zelda 1, Hikari Shinwa, and Takeshi no Chosenjo. Games other than those listed here use this feature.

-


-

Input Presets

-


-

This feature allow you to set the current input configuration to one of three presets.  This gives you the option to quickly change from one input configuration to another (such as toggling between 1 or 2 controllers and/or toggling from controller 2 being bound to controller 1 or having its own controls).

-


-

To assign the current input configuration to a preset press the down arrow next to one of the presets.  To assign the preset as the current input configuration press the up arrow or use the hotkey assigned to that specific preset.  Preset hotkeys can be assigned in the Map Hotkeys menu.

-


-

Disable left+right/up+down

-


-

By default FCEUX allows you to press both the left and right controls at the same time (or up and down).  To disable this feature uncheck the checkbox on the left.

-


-

Auto-Hold

-


-

Clicking the auto hold button will allow you to assign a hotkey to the auto-hold feature.  

-

Clicking the clear button will allow you to assign a hotkey to the clear auto-holds feature.

-


-

To use this feature, close the input config window and return to the FCEUX main window.  Hold down the auto-hold hotkey and press one of your controller inputs.  This will add it as one of the auto-hold assignments.  The game will keep auto-hold assigned buttons held be default.  Pressing one of these keys will release the button for the duration that it is held.

-


-

To turn off all auto-hold assignments press the clear auto-holds hotkey.

-


-

-

Created with the Personal Edition of HelpNDoc: Generate EPub eBooks with ease

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Input

+ +
+ +

+

Input Configuration

+


+


+

Setting up controllers

+


+

On the pull down menus, you can select the device you want to be emulated on input ports 1 and 2 (game pad, zapper, pad, paddle). Note: you can't change this setting while a movie is being played or recorded.

+

If you check the box labeled "Attach four-score(implies four gamepads)", you won't be able to select any of these options, because the four-score allows to use 2 extra controllers.

+

The device currently being emulated on each port is listed above the drop down list; loading certain games will override your settings, but only temporarily.

+


+

To bind these controls to specific keys/joystick controls use the  "configure" the device listed above each drop-down list.

+


+

Zapper / Arkanoid Paddle

+


+

Most Zapper NES games expect the Zapper to be plugged into port 2. and most VS Unisystem games expect the Zapper to be plugged into port 1.

+


+

The left mouse button is the emulated trigger button for the Zapper. The right mouse button is also emulated as the trigger, but as long as you have the right mouse button held down, no color detection will take place, which is effectively like pulling the trigger while the Zapper is pointed away from the television screen. Note that you must hold the right button down for a short time to have the desired effect. 

+


+

The Arkanoid Paddle emulates the same way the zapper.

+


+

Power Pad A / B

+


+

Emulates the NES Power pad.  The 12 pad buttons can be routed via the configure button.  FCEUX allows up to 2 Power Pads to be emulated at once (Power Pad A and B).

+


+

Famicom Controllers

+


+

You can also select the input device to be emulated on the Famicom Expansion port.  If you select a device for the Famicom Expansion Port, you should probably have emulated game pads on the emulated NES-style input ports. 

+


+

In addition to the traditional famicom controller, FCEUX can emulate the Famicom version of the Arkanoid controller, the "Space Shadow" gun, the Famicom 4-player adapter, the Family Keyboard, the HyperShot controller, the Mahjong controller, the Oeka Kids tablet, the Quiz King buzzers, the Family Trainer, and the Barcode World barcode reader.

+


+

Replace Port 2 Start With Microphone

+


+

Checking this box will replace the Start button used by controller 2 with the microphone option found on the famicom. Pressing the Microphone button is like blowing or yelling into it on the console equipment. The Port 2 controller used for the Famicom included a microphone and a volume control in place of the Start and Select buttons. This option isn't automatically detected, so it has to be manually enabled by the user. Movie files may also enable and use this feature. Both Famicom Cartridges and Famicom Disks have made use of this feature, such as both the cartridge and disk version of Zelda 1, Hikari Shinwa, and Takeshi no Chosenjo. Games other than those listed here use this feature.

+


+

Input Presets

+


+

This feature allow you to set the current input configuration to one of three presets.  This gives you the option to quickly change from one input configuration to another (such as toggling between 1 or 2 controllers and/or toggling from controller 2 being bound to controller 1 or having its own controls).

+


+

To assign the current input configuration to a preset press the down arrow next to one of the presets.  To assign the preset as the current input configuration press the up arrow or use the hotkey assigned to that specific preset.  Preset hotkeys can be assigned in the Map Hotkeys menu.

+


+

Disable left+right/up+down

+


+

By default FCEUX allows you to press both the left and right controls at the same time (or up and down).  To disable this feature uncheck the checkbox on the left. 

+


+

Auto-Hold

+


+

Clicking the auto hold button will allow you to assign a hotkey to the auto-hold feature.  

+

Clicking the clear button will allow you to assign a hotkey to the clear auto-holds feature.

+


+

To use this feature, close the input config window and return to the FCEUX main window.  Hold down the auto-hold hotkey and press one of your controller inputs.  This will add it as one of the auto-hold assignments.  The game will keep auto-hold assigned buttons held be default.  Pressing one of these keys will release the button for the duration that it is held.

+


+

To turn off all auto-hold assignments press the clear auto-holds hotkey.

+


+

+

Created with the Personal Edition of HelpNDoc: What is a Help Authoring tool?

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Intro.html b/web/help/Intro.html index b5a4a1ba..1d797b27 100644 --- a/web/help/Intro.html +++ b/web/help/Intro.html @@ -1,76 +1,273 @@ - - + + + + + - Introduction - - - - - - - - - - + + + + + + + + Introduction + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Introduction

- -
-
- Next - -
-
-
-
- -

-

Introduction

-


-

Basic information about FCEUX and its features.

-


-

Introduction

-


-

Overview

-


-

FCE Ultra Version History

-


-

What's Combined In FCEUX?

-

-

Created with the Personal Edition of HelpNDoc: Write EPub books for the iPad

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Introduction

+ +
+ +

+

Introduction

+


+

Basic information about FCEUX and its features.

+


+

Introduction

+


+

Overview

+


+

FCE Ultra Version History

+


+

What's Combined In FCEUX?

+

+

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Introduction.html b/web/help/Introduction.html index c5b91ce2..fee1a633 100644 --- a/web/help/Introduction.html +++ b/web/help/Introduction.html @@ -1,113 +1,304 @@ - - + + + + + - Introduction - - - - - - - - - - + + + + + + + + Introduction + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Introduction

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Welcome to the FCEUX Help menu.

-


-

The following information is about how to use FCEUX, its commands, how to use FCEUX to its fullest, and the communities for which FCEUX is designed.

-


-


-

Introduction

-


-

Basic information about FCEUX and its features.

-

Overview

-

FCE Ultra Version History

-

What's Combined In FCEUX?

-


-


-

Additional Chapters

-


-

General

-

Guides for general uses of FCEUX and the FCEUX NES menu.

-


-

Config

-

Commands under FCEUX Config menu.

-


-

Tools

-

Commands under FCEUX Tools menu.

-


-

Debug

-

Commands under FCEUX Debug menu.

-


-

FAQ / Guides

-

Information regarding various concepts such as TAS, ROM Hacking, RAM Mapping.

-


-

Technical Information

-

Technical information relating to NES hardware emulation & FCEUX file formats.

-


-


-


-


-

Help menu created by adelikat.

-

Updated & maintained by AnS.

-

Information collected and/or written/edited by adelikat and AnS.

-

Minor edits of lua-related text by FatRatKnight.

-

Debugger documentation edits by rainwarrior.

-


-

-

Created with the Personal Edition of HelpNDoc: Free help authoring environment

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Introduction

+ +
+ +

+

Welcome to the FCEUX Help menu.

+


+

The following information is about how to use FCEUX, its commands, how to use FCEUX to its fullest, and the communities for which FCEUX is designed.

+


+


+

Introduction

+


+

Basic information about FCEUX and its features.

+

Overview

+

FCE Ultra Version History

+

What's Combined In FCEUX?

+


+


+

Additional Chapters

+


+

General

+

Guides for general uses of FCEUX and the FCEUX NES menu.

+


+

Config

+

Commands under FCEUX Config menu.

+


+

Tools

+

Commands under FCEUX Tools menu.

+


+

Debug

+

Commands under FCEUX Debug menu.

+


+

FAQ / Guides

+

Information regarding various concepts such as TAS, ROM Hacking, RAM Mapping.

+


+

Technical Information

+

Technical information relating to NES hardware emulation & FCEUX file formats.

+


+


+


+


+

Help menu created by adelikat.

+

Updated & maintained by AnS.

+

Information collected and/or written/edited by adelikat and AnS.

+

Minor edits of lua-related text by FatRatKnight.

+

Debugger documentation edits by rainwarrior.

+


+

+

Created with the Personal Edition of HelpNDoc: Easy EPub and documentation editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/LuaBot.html b/web/help/LuaBot.html index f5d98727..05b836ca 100644 --- a/web/help/LuaBot.html +++ b/web/help/LuaBot.html @@ -1,219 +1,410 @@ - - + + + + + - Lua Bot - - - - - - - - - - + + + + + + + + Lua Bot + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Lua Bot

- -
- Lua Scripting ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

LuaBot

-


-

LuaBot employs a new concept in FCEUX Tool creation.  It is an external lua script that creates the Basic bot GUI.  The GUI then uses lua scripting to perform botting tasks.

-


-

To run it you must have lua scripting enabled (see Getting Started).  LuaBot is included in the lua pack under /luaScripts.  to get started run  luabot_framework.lua.

-


-

What is Lua Bot?

-

LuaBot is...well, a bot. It uses a combination of probability, scripting and RAM monitoring to play games.  Specifically  basic bot is used to create portions of Tool Assisted Speedrun.   It is most powerful for finding solutions in highly random situations, or highly improbably events (such as manipulating a critical hit in an RPG).  Basic bot comes with a rather powerful scripting language in order to be "programmed" to handle these specific situations.  LuaBot in its most extreme application can even be "taught" to play video games!

-


-


-

How to Use Lua Bot

-


-

LuaBot is a trial and error script that exhausts the input-search-space by simply trying to push buttons.

-


-

You can program it to limit this searchspace, as it can become exponentially large. You can press eight possible buttons at any frame, each on or off. That's 2 raised to the 8, or 256 possible combinations in that one frame. There are 60 frames in one second, so you have 256 raised to the power of 60. Write a three. Now start writing 144 zeroes after it. It's not a small number.

-


-

Anyways, the bot has two parts. The frontend, which we'll call BeeBee, and the Lua part, which we call LuaBot.

-


-

You start the bot by opening the LuaBot_front.lua script file. Make sure the LuaBot_backend.lua file is in the same directory.

-


-

BeeBee

-


-

BeeBee (who received it's name from BasicBot, its predecessor) just writes it's contents into the LuaBot framework and produces a big Lua script for you.

-

All you need to do is enter Lua code for the specific functions and the code will generate the script.

-


-

You can also save and load the contents of the front-end. That way you can easily manage your bot scripts, without actually having to look into the LuaBot code.

-


-

BeeBee is only a pasting mechanism. It does not compile Lua or warn for errors.

-


-

LuaBot

-


-

LuaBot is a generic trial-and-error script that serves as a bot framework. It will set inputs as you program them for a number of frames (called an attempt). When the isAttemptEnd() says the attempt ends, a new attempt is started. All the attempts fall under one segment. At the end of a segment (denoted by the isSegmentEnd() function), the best attempt is kept (judged by the score and tie functions) and the next segment is started. The bot is capable of rolling back if a segment runs into a dead end. This allows you to backtrack and restart a previous segment.

-


-

The bot evaluates a true or false by checking to see whether the return value of a function is bigger then a certain value. It does this for EVERY function that returns something and every function that returns something must return a number (or Lua _will_ complain). For absolute true or false you can return "yes" and "no", "maxvalue" and "minvalue" or "pressed" and "released". Read variable info for more information.

-


-

The script takes a number of variables and functions into account. Some variables become important to prevent desyncing over segments.

-


-

- maxvalue

-

The maximum value (exclusive) of the random evaluation. If a value is higher than rand(minvalue, maxvalue), it evaluates as true, else false. By default this is set to 100.

-


-

- minvalue

-

The lowest value (inclusive) of the random evaluation. If a value is lower than rand(minvalue, maxvalue), it evaluates to false, else true. By default this is set to 0.

-


-

- yes / no

-

- pressed / released

-

These map to the minvalue/maxvalue.

-


-

- loopcounter

-

The number of times a frameadvance has been called by the main botloop.

-


-

- key1 key2 key3 key4

-

The input table of players 1-4. The keys are: A B up down left right select start. Set any to 1 if you want them to be set and to nil if you don't want them set.

-

Note that these get cleared right before onInputStart is called. This variable is saved in a pseudo-movie table if the attempt is better then the previous one and used for playback when moving to the next segment.

-


-

- lastkey1 lastkey2 lastkey3 lastkey4

-

The inputs that were given to FCEU on the PREVIOUS frame. This holds for segments as well (at the beginning of a new segment, the lastkeys of the previous segment are set). This also goes for the start. If you use key1-4 in onStart, the first segment will have those keys as lastkey.

-


-

- frame

-

The number of frames of the current attempt. Starts at 1.

-


-

- attempt

-

The number of attempts in the current segment. Starts at 1.

-


-

- segment

-

The segment the bot is currently running. Note that rolledback segments are deducted from this number.

-


-

- okattempts

-

The number of attempts that have been deemed ok. This is a statistical variable. It might tell you how well your bot is doing (combined with the number of failed attempts).

-


-

- failattempts

-

The number of attempts in the current segment that have been deemed bad. This is a statistical variable. It might tell you how well your bot is doing (combined with the number of approved attempts).

-


-

- segments

-

This is the big table that holds everything together. Don't mess with it.

-


-

- maxframes

-

You can set maxframes and check it in the isAttemptEnd function to simply limit a attempt by this many frames. You can also just ignore this and do something else instead.

-


-

- maxattempts

-

Same as maxframes, except for attempts in a segment.

-


-

- maxsegments

-

Same as maxframes, except for segments in a run.

-


-

- playingbest

-

Will be set to true when the bot is playing back it's best attempt to advance to the next segment. Not really used by other functions.

-


-

- keyrecording1-4

-

A simple table with the pressed keys for playback.

-


-

- X Y Z P Q

-

Some "static" variables. These allow you to easily set them onStart and use them in various functions to return the same number. Like a global variable. The P and Q numbers used to denote a random number between 0 and P or Q, but they don't right now.

-


-

- vars

-

This is your variable table. It's contents is saved at the end of an attempt and will be loaded at the beginning of a segment. On rollback, this table is also kept. Put any variable you want to keep across segments in this table.

-


-


-

Ok. That's it for the variables. Now for functions. There are basically three types of functions. The functions that determine whether a button is pressed (8 for each player), to determine whether an attempt/segment/run has ended or was ok and functions for certain events. This number is not evaluated by the random-eval function.

-


-

- getScore

-

This returns how "well" the current attempt is. At the end of a segment, the best scoring good attempt will be used to continue to the next segment. In case of a tie, see the tie functions. This number is not evaluated by the random-eval function!

-


-

- getTie1-4

-

If the score ends in a tie, that is, two attempts score equally well (have an equal number of points for instance), you can use these functions to break that tie. Like, which attempt has the most health or is the fastest or whatever. This number is not evaluated by the random-eval function!

-


-

- isRunEnd

-

Return whether the bot should stop running. If the returned number is bigger then the random number rand(minvalue-maxvalue), the bot will stop.

-


-

- mustRollBack

-

Returns whether the bot should rollback the current attempt. In such case, the previous segment is loaded and the current segment is completely discarded. If the returned number is bigger then the random number rand(minvalue-maxvalue), the segment will rollback one segment.

-


-

- isSegmentEnd

-

If the returned number is bigger then the random number rand(minvalue-maxvalue), the bot will stop the current segment, play back the best recorded attempt and start a new segment. Mostly done when a certain number of attempts is reached, but possibly you know when have the best possible attempt and can move on.

-


-

- isAttemptEnd

-

If the returned number is bigger then the random number rand(minvalue-maxvalue), the attempt will stop and a new attempt will be started. Some examples when this function should return yes is when you reached a certain goal, a number of frames or when you died (in which case the bot should try again :).

-


-

- isAttemptOk

-

If the returned number is bigger then the random number rand(minvalue-maxvalue), the current attempt (which has just ended) is deemed ok. Only attempts that are deemed ok are up for being saved. For instance, when the player died in the current attempt, you should return no.

-


-

- pressKeyX (pressKeyA1, pressKeyStart4, etc...)

-

These functions determine whether a button should be pressed in the next frame. If the returned number is bigger then the random number rand(minvalue-maxvalue), the button is pressed, otherwise it is not. To absolutely press a button, simply return yes or no. To use some odds, return a number between minvalue and maxvalue. For instance, using the default settings, if you return 50, there is a 50% chance the button will be pressed.

-


-

- onStart

-

Maybe a little misleading, but the onStart function is called BEFORE the main botloop starts. You can do some non-generic startup stuff here like press start at the title screen and get the game started. Returns nothing.

-


-

- onFinish

-

The opposite to onStart, this function is called when the main botloop exits. You can cleanup, or write stuff or whatever.

-


-

- onSegmentStart

-

When a new segment is started, this is called. After initializing variables and such, but before onAttemptStart is called. Returns nothing.

-


-

- onSegmentEnd

-

When isSegmentEnd evaluates to true, this function is called. Returns nothing.

-


-

- onAttemptStart

-

Called at the start of a new attempt, after onSegmentStart (in case of a new segment) but before onInputStart. Returns nothing.

-


-

- onAttemptEnd(wasOk)

-

Called at the end of an attempt. The only function to have a parameter (note: case sensitive). The parameter wasOk will return (boolean) whether isAttemptOk evaluated to true or false. Returns nothing.

-


-

- onInputStart

-

In a frame, this is the first place where the key1-4 variables are cleared. This is called before all the input (pressKeyX) functions are called. Returns nothing.

-


-

- onInputEnd

-

This is called immediately after the input (pressKeyX) functions have been called. Returns nothing.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Lua Bot

+ +
+ +

+

LuaBot

+


+

LuaBot employs a new concept in FCEUX Tool creation.  It is an external lua script that creates the Basic bot GUI.  The GUI then uses lua scripting to perform botting tasks.

+


+

To run it you must have lua scripting enabled (see Getting Started).  LuaBot is included in the lua pack under /luaScripts.  to get started run  luabot_framework.lua.

+


+

What is Lua Bot?

+

LuaBot is...well, a bot. It uses a combination of probability, scripting and RAM monitoring to play games.  Specifically  basic bot is used to create portions of Tool Assisted Speedrun.   It is most powerful for finding solutions in highly random situations, or highly improbably events (such as manipulating a critical hit in an RPG).  Basic bot comes with a rather powerful scripting language in order to be "programmed" to handle these specific situations.  LuaBot in its most extreme application can even be "taught" to play video games!

+


+


+

How to Use Lua Bot

+


+

LuaBot is a trial and error script that exhausts the input-search-space by simply trying to push buttons. 

+


+

You can program it to limit this searchspace, as it can become exponentially large. You can press eight possible buttons at any frame, each on or off. That's 2 raised to the 8, or 256 possible combinations in that one frame. There are 60 frames in one second, so you have 256 raised to the power of 60. Write a three. Now start writing 144 zeroes after it. It's not a small number.

+


+

Anyways, the bot has two parts. The frontend, which we'll call BeeBee, and the Lua part, which we call LuaBot.

+


+

You start the bot by opening the LuaBot_front.lua script file. Make sure the LuaBot_backend.lua file is in the same directory.

+


+

BeeBee

+


+

BeeBee (who received it's name from BasicBot, its predecessor) just writes it's contents into the LuaBot framework and produces a big Lua script for you.

+

All you need to do is enter Lua code for the specific functions and the code will generate the script.

+


+

You can also save and load the contents of the front-end. That way you can easily manage your bot scripts, without actually having to look into the LuaBot code.

+


+

BeeBee is only a pasting mechanism. It does not compile Lua or warn for errors.

+


+

LuaBot

+


+

LuaBot is a generic trial-and-error script that serves as a bot framework. It will set inputs as you program them for a number of frames (called an attempt). When the isAttemptEnd() says the attempt ends, a new attempt is started. All the attempts fall under one segment. At the end of a segment (denoted by the isSegmentEnd() function), the best attempt is kept (judged by the score and tie functions) and the next segment is started. The bot is capable of rolling back if a segment runs into a dead end. This allows you to backtrack and restart a previous segment.

+


+

The bot evaluates a true or false by checking to see whether the return value of a function is bigger then a certain value. It does this for EVERY function that returns something and every function that returns something must return a number (or Lua _will_ complain). For absolute true or false you can return "yes" and "no", "maxvalue" and "minvalue" or "pressed" and "released". Read variable info for more information.

+


+

The script takes a number of variables and functions into account. Some variables become important to prevent desyncing over segments.

+


+

- maxvalue

+

The maximum value (exclusive) of the random evaluation. If a value is higher than rand(minvalue, maxvalue), it evaluates as true, else false. By default this is set to 100.

+


+

- minvalue

+

The lowest value (inclusive) of the random evaluation. If a value is lower than rand(minvalue, maxvalue), it evaluates to false, else true. By default this is set to 0.

+


+

- yes / no

+

- pressed / released

+

These map to the minvalue/maxvalue.

+


+

- loopcounter

+

The number of times a frameadvance has been called by the main botloop.

+


+

- key1 key2 key3 key4

+

The input table of players 1-4. The keys are: A B up down left right select start. Set any to 1 if you want them to be set and to nil if you don't want them set.

+

Note that these get cleared right before onInputStart is called. This variable is saved in a pseudo-movie table if the attempt is better then the previous one and used for playback when moving to the next segment.

+


+

- lastkey1 lastkey2 lastkey3 lastkey4

+

The inputs that were given to FCEU on the PREVIOUS frame. This holds for segments as well (at the beginning of a new segment, the lastkeys of the previous segment are set). This also goes for the start. If you use key1-4 in onStart, the first segment will have those keys as lastkey.

+


+

- frame

+

The number of frames of the current attempt. Starts at 1.

+


+

- attempt

+

The number of attempts in the current segment. Starts at 1.

+


+

- segment

+

The segment the bot is currently running. Note that rolledback segments are deducted from this number.

+


+

- okattempts

+

The number of attempts that have been deemed ok. This is a statistical variable. It might tell you how well your bot is doing (combined with the number of failed attempts).

+


+

- failattempts

+

The number of attempts in the current segment that have been deemed bad. This is a statistical variable. It might tell you how well your bot is doing (combined with the number of approved attempts).

+


+

- segments

+

This is the big table that holds everything together. Don't mess with it.

+


+

- maxframes

+

You can set maxframes and check it in the isAttemptEnd function to simply limit a attempt by this many frames. You can also just ignore this and do something else instead.

+


+

- maxattempts

+

Same as maxframes, except for attempts in a segment.

+


+

- maxsegments

+

Same as maxframes, except for segments in a run.

+


+

- playingbest

+

Will be set to true when the bot is playing back it's best attempt to advance to the next segment. Not really used by other functions.

+


+

- keyrecording1-4

+

A simple table with the pressed keys for playback.

+


+

- X Y Z P Q

+

Some "static" variables. These allow you to easily set them onStart and use them in various functions to return the same number. Like a global variable. The P and Q numbers used to denote a random number between 0 and P or Q, but they don't right now.

+


+

- vars

+

This is your variable table. It's contents is saved at the end of an attempt and will be loaded at the beginning of a segment. On rollback, this table is also kept. Put any variable you want to keep across segments in this table.

+


+


+

Ok. That's it for the variables. Now for functions. There are basically three types of functions. The functions that determine whether a button is pressed (8 for each player), to determine whether an attempt/segment/run has ended or was ok and functions for certain events. This number is not evaluated by the random-eval function.

+


+

- getScore

+

This returns how "well" the current attempt is. At the end of a segment, the best scoring good attempt will be used to continue to the next segment. In case of a tie, see the tie functions. This number is not evaluated by the random-eval function!

+


+

- getTie1-4

+

If the score ends in a tie, that is, two attempts score equally well (have an equal number of points for instance), you can use these functions to break that tie. Like, which attempt has the most health or is the fastest or whatever. This number is not evaluated by the random-eval function!

+


+

- isRunEnd

+

Return whether the bot should stop running. If the returned number is bigger then the random number rand(minvalue-maxvalue), the bot will stop.

+


+

- mustRollBack

+

Returns whether the bot should rollback the current attempt. In such case, the previous segment is loaded and the current segment is completely discarded. If the returned number is bigger then the random number rand(minvalue-maxvalue), the segment will rollback one segment.

+


+

- isSegmentEnd

+

If the returned number is bigger then the random number rand(minvalue-maxvalue), the bot will stop the current segment, play back the best recorded attempt and start a new segment. Mostly done when a certain number of attempts is reached, but possibly you know when have the best possible attempt and can move on.

+


+

- isAttemptEnd

+

If the returned number is bigger then the random number rand(minvalue-maxvalue), the attempt will stop and a new attempt will be started. Some examples when this function should return yes is when you reached a certain goal, a number of frames or when you died (in which case the bot should try again :).

+


+

- isAttemptOk

+

If the returned number is bigger then the random number rand(minvalue-maxvalue), the current attempt (which has just ended) is deemed ok. Only attempts that are deemed ok are up for being saved. For instance, when the player died in the current attempt, you should return no.

+


+

- pressKeyX (pressKeyA1, pressKeyStart4, etc...)

+

These functions determine whether a button should be pressed in the next frame. If the returned number is bigger then the random number rand(minvalue-maxvalue), the button is pressed, otherwise it is not. To absolutely press a button, simply return yes or no. To use some odds, return a number between minvalue and maxvalue. For instance, using the default settings, if you return 50, there is a 50% chance the button will be pressed.

+


+

- onStart

+

Maybe a little misleading, but the onStart function is called BEFORE the main botloop starts. You can do some non-generic startup stuff here like press start at the title screen and get the game started. Returns nothing.

+


+

- onFinish

+

The opposite to onStart, this function is called when the main botloop exits. You can cleanup, or write stuff or whatever.

+


+

- onSegmentStart

+

When a new segment is started, this is called. After initializing variables and such, but before onAttemptStart is called. Returns nothing.

+


+

- onSegmentEnd

+

When isSegmentEnd evaluates to true, this function is called. Returns nothing.

+


+

- onAttemptStart

+

Called at the start of a new attempt, after onSegmentStart (in case of a new segment) but before onInputStart. Returns nothing.

+


+

- onAttemptEnd(wasOk)

+

Called at the end of an attempt. The only function to have a parameter (note: case sensitive). The parameter wasOk will return (boolean) whether isAttemptOk evaluated to true or false. Returns nothing.

+


+

- onInputStart

+

In a frame, this is the first place where the key1-4 variables are cleared. This is called before all the input (pressKeyX) functions are called. Returns nothing.

+


+

- onInputEnd

+

This is called immediately after the input (pressKeyX) functions have been called. Returns nothing.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create PDF Help documents

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/LuaFunctionsList.html b/web/help/LuaFunctionsList.html index 120bb3e8..223d8d23 100644 --- a/web/help/LuaFunctionsList.html +++ b/web/help/LuaFunctionsList.html @@ -1,871 +1,1027 @@ - + + + + - Lua Functions List - - - - - - - - - - + + + + + + + + Lua Functions List + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Lua Functions List

- -
- Lua Scripting ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Lua Functions List

+ +
+

-

Lua Functions

-


-

The following functions are available in FCEUX, in addition to standard LUA capabilities:

-


-


-

Emu library

-


-

emu.poweron()

-


-

Executes a power cycle.

-


-

emu.softreset()

-


-

Executes a (soft) reset.

-


-

emu.speedmode(string mode)

-


-

Set the emulator to given speed. The mode argument can be one of these:

-

       - "normal"

-

       - "nothrottle" (same as turbo on fceux)

-

       - "turbo"

-

       - "maximum"

-


-

emu.frameadvance()

-


-

Advance the emulator by one frame. It's like pressing the frame advance button once.

-


-

Most scripts use this function in their main game loop to advance frames. Note that you can also register functions by various methods that run "dead", returning control to the emulator and letting the emulator advance the frame.  For most people, using frame advance in an endless while loop is easier to comprehend so I suggest  starting with that.  This makes more sense when creating bots. Once you move to creating auxillary libraries, try the register() methods.

-


-

emu.pause()

-


-

Pauses the emulator.

-


-

emu.unpause()

-


-

Unpauses the emulator.

-


-

emu.exec_count(int count, function func)

-


-

Calls given function, restricting its working time to given number of lua cycles. Using this method you can ensure that some heavy operation (like Lua bot) won't freeze FCEUX.

-


-

emu.exec_time(int time, function func)

-


-

Windows-only. Calls given function, restricting its working time to given number of milliseconds (approximate). Using this method you can ensure that some heavy operation (like Lua bot) won't freeze FCEUX.

-


-

emu.setrenderplanes(bool sprites, bool background)

-


-

Toggles the drawing of the sprites and background planes. Set to false or nil to disable a pane, anything else will draw them.

-


-

emu.message(string message)

-


-

Displays given message on screen in the standard messages position. Use gui.text() when you need to position text.

-


-

int emu.framecount()

-


-

Returns the framecount value. The frame counter runs without a movie running so this always returns a value.

-


-

int emu.lagcount()

-


-

Returns the number of lag frames encountered. Lag frames are frames where the game did not poll for input because it missed the vblank. This happens when it has to compute too much within the frame boundary. This returns the number indicated on the lag counter.

-


-

bool emu.lagged()

-


-

Returns true if currently in a lagframe, false otherwise.

-


-

emu.setlagflag(bool value)

-


-

Sets current value of lag flag.

-

Some games poll input even in lag frames, so standard way of detecting lag (used by FCEUX and other emulators) does not work for those games, and you have to determine lag frames manually.

-

First, find RAM addresses that help you distinguish between lag and non-lag frames (e.g. an in-game frame counter that only increments in non-lag frames). Then register memory hooks that will change lag flag when needed.

-


-

bool emu.emulating()

-


-

Returns true if emulation has started, or false otherwise. Certain operations such as using savestates are invalid to attempt before emulation has started. You probably won't need to use this function unless you want to make your script extra-robust to being started too early.

-


-

bool emu.paused()

-


-

Returns true if emulator is paused, false otherwise.

-


-

bool emu.readonly()

-

Alias: movie.readonly

-


-

Returns whether the emulator is in read-only state.  

-


-

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

-


-

emu.setreadonly(bool state)

-

Alias: movie.setreadonly

-


-

Sets the read-only status to read-only if argument is true and read+write if false.

-

Note: This might result in an error if the medium of the movie file is not writeable (such as in an archive file).

-


-

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

-


-

emu.getdir()

-


-

Returns the path of fceux.exe as a string.

-


-

emu.loadrom(string filename)

-


-

Loads the ROM from the directory relative to the lua script or from the absolute path. Hence, the filename parameter can be absolute or relative path.

-


-

If the ROM can't be loaded, loads the most recent one.

-


-

emu.registerbefore(function func)

-


-

Registers a callback function to run immediately before each frame gets emulated. This runs after the next frame's input is known but before it's used, so this is your only chance to set the next frame's input using the next frame's would-be input. For example, if you want to make a script that filters or modifies ongoing user input, such as making the game think "left" is pressed whenever you press "right", you can do it easily with this.

-


-

Note that this is not quite the same as code that's placed before a call to emu.frameadvance. This callback runs a little later than that. Also, you cannot safely assume that this will only be called once per frame. Depending on the emulator's options, every frame may be simulated multiple times and your callback will be called once per simulation. If for some reason you need to use this callback to keep track of a stateful linear progression of things across frames then you may need to key your calculations to the results of emu.framecount.

-


-

Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to emu.registerbefore will return the old callback. You may register nil instead of a function to clear a previously-registered callback. If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.

-


-

emu.registerafter(function func)

-


-

Registers a callback function to run immediately after each frame gets emulated. It runs at a similar time as (and slightly before) gui.register callbacks, except unlike with gui.register it doesn't also get called again whenever the screen gets redrawn. Similar caveats as those mentioned in emu.registerbefore apply.

-


-

emu.registerexit(function func)

-


-

Registers a callback function that runs when the script stops. Whether the script stops on its own or the user tells it to stop, or even if the script crashes or the user tries to close the emulator, FCEUX will try to run whatever Lua code you put in here first. So if you want to make sure some code runs that cleans up some external resources or saves your progress to a file or just says some last words, you could put it here. (Of course, a forceful termination of the application or a crash from inside the registered exit function will still prevent the code from running.)

-


-

Suppose you write a script that registers an exit function and then enters an infinite loop. If the user clicks "Stop" your script will be forcefully stopped, but then it will start running its exit function. If your exit function enters an infinite loop too, then the user will have to click "Stop" a second time to really stop your script. That would be annoying. So try to avoid doing too much inside the exit function.

-


-

Note that restarting a script counts as stopping it and then starting it again, so doing so (either by clicking "Restart" or by editing the script while it is running) will trigger the callback. Note also that returning from a script generally does NOT count as stopping (because your script is still running or waiting to run its callback functions and thus does not stop... see here for more information), even if the exit callback is the only one you have registered.

-


-

bool emu.addgamegenie(string str)

-


-

Adds a Game Genie code to the Cheats menu. Returns false and an error message if the code can't be decoded. Returns false if the code couldn't be added. Returns true if the code already existed, or if it was added.

-


-

Usage: emu.addgamegenie("NUTANT")

-


-

Note that the Cheats Dialog Box won't show the code unless you close and reopen it.

-


-

bool emu.delgamegenie(string str)

-


-

Removes a Game Genie code from the Cheats menu. Returns false and an error message if the code can't be decoded. Returns false if the code couldn't be deleted. Returns true if the code didn't exist, or if it was deleted.

-


-

Usage: emu.delgamegenie("NUTANT")

-


-

Note that the Cheats Dialog Box won't show the code unless you close and reopen it.

-


-

emu.print(string str)

-


-

Puts a message into the Output Console area of the Lua Script control window. Useful for displaying usage instructions to the user when a script gets run.

-


-

emu.getscreenpixel(int x, int y, bool getemuscreen)

-


-

Returns the separate RGB components of the given screen pixel, and the palette. Can be 0-255 by 0-239, but NTSC only displays 0-255 x 8-231 of it. If getemuscreen is false, this gets background colors from either the screen pixel or the LUA pixels set, but LUA data may not match the information used to put the data to the screen. If getemuscreen is true, this gets background colors from anything behind an LUA screen element.

-


-

Usage is local r,g,b,palette = emu.getscreenpixel(5, 5, false) to retrieve the current red/green/blue colors and palette value of the pixel at 5x5.

-


-

Palette value can be 0-63, or 254 if there was an error.

-


-

You can avoid getting LUA data by putting the data into a function, and feeding the function name to emu.registerbefore.

-


-


-

FCEU library

-


-

The FCEU library is the same as the emu library. It is left in for backwards compatibility. However, the emu library is preferred.

-


-


-

ROM Library

-


-

rom.getfilename()

-


-

Get the base filename of the ROM loaded.

-


-

rom.gethash(string type)

-


-

Get a hash of the ROM loaded, for verification. If type is "md5", returns a hex string of the MD5 hash. If type is "base64", returns a base64 string of the MD5 hash, just like the movie romChecksum value.

-


-

rom.readbyte(int address)

-

rom.readbyteunsigned(int address)

-


-

Get an unsigned byte from the actual ROM file at the given address.  

-


-

This includes the header! It's the same as opening the file in a hex-editor.

-


-

rom.readbytesigned(int address)

-


-

Get a signed byte from the actual ROM file at the given address. Returns a byte that is signed.

-


-

This includes the header! It's the same as opening the file in a hex-editor.

-


-

rom.writebyte()

-


-

Write the value to the ROM at the given address. The value is modded with 256 before writing (so writing 257 will actually write 1). Negative values allowed.

-


-

Editing the header is not available.

-


-

Memory Library

-


-

memory.readbyte(int address)

-

memory.readbyteunsigned(int address)

-


-

Get an unsigned byte from the RAM at the given address. Returns a byte regardless of emulator. The byte will always be positive.

-


-

memory.readbyterange(int address, int length)

-


-

Get a length bytes starting at the given address and return it as a string. Convert to table to access the individual bytes.

-


-

memory.readbytesigned(int address)

-


-

Get a signed byte from the RAM at the given address. Returns a byte regardless of emulator. The most significant bit will serve as the sign.

-


-

memory.readword(int addressLow, [int addressHigh])

-

memory.readwordunsigned(int addressLow, [int addressHigh])

-


-

Get an unsigned word from the RAM at the given address. Returns a 16-bit value regardless of emulator. The value will always be positive.

-

If you only provide a single parameter (addressLow), the function treats it as address of little-endian word. if you provide two parameters, the function reads the low byte from addressLow and the high byte from addressHigh, so you can use it in games which like to store their variables in separate form (a lot of NES games do).

-


-

memory.readwordsigned(int addressLow, [int addressHigh])

-


-

The same as above, except the returned value is signed, i.e. its most significant bit will serve as the sign.

-


-

memory.writebyte(int address, int value)

-


-

Write the value to the RAM at the given address. The value is modded with 256 before writing (so writing 257 will actually write 1). Negative values allowed.

-


-

int memory.getregister(cpuregistername)

-


-

Returns the current value of the given hardware register.

-

For example, memory.getregister("pc") will return the main CPU's current Program Counter.

-


-

Valid registers are: "a", "x", "y", "s", "p", and "pc".

-


-

memory.setregister(string cpuregistername, int value)

-


-

Sets the current value of the given hardware register.

-

For example, memory.setregister("pc",0x200) will change the main CPU's current Program Counter to 0x200.

-


-

Valid registers are: "a", "x", "y", "s", "p", and "pc".

-


-

You had better know exactly what you're doing or you're probably just going to crash the game if you try to use this function. That applies to the other memory.write functions as well, but to a lesser extent.

-

-

-

memory.register(int address, [int size,] function func)

-

memory.registerwrite(int address, [int size,] function func)

-


-

Registers a function to be called immediately whenever the given memory address range is written to.

-


-

address is the address in CPU address space (0x0000 - 0xFFFF).

-


-

size is the number of bytes to "watch". For example, if size is 100 and address is 0x0200, then you will register the function across all 100 bytes from 0x0200 to 0x0263. A write to any of those bytes will trigger the function. Having callbacks on a large range of memory addresses can be expensive, so try to use the smallest range that's necessary for whatever it is you're trying to do. If you don't specify any size then it defaults to 1.

-


-

The callback function will receive three arguments (address, size, value) indicating what write operation triggered the callback. If you don't care about that extra information then you can ignore it and define your callback function to not take any arguments. Since 6502 writes are always single byte, the "size" argument will always be 1.

-


-

You may use a memory.write function from inside the callback to change the value that just got written. However, keep in mind that doing so will trigger your callback again, so you must have a "base case" such as checking to make sure that the value is not already what you want it to be before writing it. Another, more drastic option is to de-register the current callback before performing the write.

-


-

If func is nil that means to de-register any memory write callbacks that the current script has already registered on the given range of bytes.

-


-

memory.registerexec(int address, [int size,] function func)

-

memory.registerrun(int address, [int size,] function func)

-

memory.registerexecute(int address, [int size,] function func)

-


-

Registers a function to be called immediately whenever the emulated system runs code located in the given memory address range.

-


-

Since "address" is the address in CPU address space (0x0000 - 0xFFFF), this doesn't take ROM banking into account, so the callback will be called for any bank, and in some cases you'll have to check current bank in your callback function.

-


-

The information about memory.register applies to this function as well. The callback will receive the same three arguments, though the "value" argument will always be 0.

-


-
- - - +

Lua Functions

+


+

The following functions are available in FCEUX, in addition to standard LUA capabilities:

+


+


+

Emu library

+


+

emu.poweron()

+


+

Executes a power cycle.

+


+

emu.softreset()

+


+

Executes a (soft) reset.

+


+

emu.speedmode(string mode)

+


+

Set the emulator to given speed. The mode argument can be one of these:

+

       - "normal"

+

       - "nothrottle" (same as turbo on fceux)

+

       - "turbo"

+

       - "maximum"

+


+

emu.frameadvance()

+


+

Advance the emulator by one frame. It's like pressing the frame advance button once.

+


+

Most scripts use this function in their main game loop to advance frames. Note that you can also register functions by various methods that run "dead", returning control to the emulator and letting the emulator advance the frame.  For most people, using frame advance in an endless while loop is easier to comprehend so I suggest  starting with that.  This makes more sense when creating bots. Once you move to creating auxillary libraries, try the register() methods.

+


+

emu.pause()

+


+

Pauses the emulator.

+


+

emu.unpause()

+


+

Unpauses the emulator.

+


+

emu.exec_count(int count, function func)

+


+

Calls given function, restricting its working time to given number of lua cycles. Using this method you can ensure that some heavy operation (like Lua bot) won't freeze FCEUX.

+


+

emu.exec_time(int time, function func)

+


+

Windows-only. Calls given function, restricting its working time to given number of milliseconds (approximate). Using this method you can ensure that some heavy operation (like Lua bot) won't freeze FCEUX.

+


+

emu.setrenderplanes(bool sprites, bool background)

+


+

Toggles the drawing of the sprites and background planes. Set to false or nil to disable a pane, anything else will draw them.

+


+

emu.message(string message)

+


+

Displays given message on screen in the standard messages position. Use gui.text() when you need to position text.

+


+

int emu.framecount()

+


+

Returns the framecount value. The frame counter runs without a movie running so this always returns a value.

+


+

int emu.lagcount()

+


+

Returns the number of lag frames encountered. Lag frames are frames where the game did not poll for input because it missed the vblank. This happens when it has to compute too much within the frame boundary. This returns the number indicated on the lag counter.

+


+

bool emu.lagged()

+


+

Returns true if currently in a lagframe, false otherwise.

+


+

emu.setlagflag(bool value)

+


+

Sets current value of lag flag.

+

Some games poll input even in lag frames, so standard way of detecting lag (used by FCEUX and other emulators) does not work for those games, and you have to determine lag frames manually.

+

First, find RAM addresses that help you distinguish between lag and non-lag frames (e.g. an in-game frame counter that only increments in non-lag frames). Then register memory hooks that will change lag flag when needed.

+


+

bool emu.emulating()

+


+

Returns true if emulation has started, or false otherwise. Certain operations such as using savestates are invalid to attempt before emulation has started. You probably won't need to use this function unless you want to make your script extra-robust to being started too early.

+


+

bool emu.paused()

+


+

Returns true if emulator is paused, false otherwise.

+


+

bool emu.readonly()

+

Alias: movie.readonly

+


+

Returns whether the emulator is in read-only state.  

+


+

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

+


+

emu.setreadonly(bool state)

+

Alias: movie.setreadonly

+


+

Sets the read-only status to read-only if argument is true and read+write if false.

+

Note: This might result in an error if the medium of the movie file is not writeable (such as in an archive file).

+


+

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

+


+

emu.getdir()

+


+

Returns the path of fceux.exe as a string.

+


+

emu.loadrom(string filename)

+


+

Loads the ROM from the directory relative to the lua script or from the absolute path. Hence, the filename parameter can be absolute or relative path.

+


+

If the ROM can't e loaded, loads the most recent one.

+


+

emu.registerbefore(function func)

+


+

Registers a callback function to run immediately before each frame gets emulated. This runs after the next frame's input is known but before it's used, so this is your only chance to set the next frame's input using the next frame's would-be input. For example, if you want to make a script that filters or modifies ongoing user input, such as making the game think "left" is pressed whenever you press "right", you can do it easily with this.

+


+

Note that this is not quite the same as code that's placed before a call to emu.frameadvance. This callback runs a little later than that. Also, you cannot safely assume that this will only be called once per frame. Depending on the emulator's options, every frame may be simulated multiple times and your callback will be called once per simulation. If for some reason you need to use this callback to keep track of a stateful linear progression of things across frames then you may need to key your calculations to the results of emu.framecount.

+


+

Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to emu.registerbefore will return the old callback. You may register nil instead of a function to clear a previously-registered callback. If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.

+


+

emu.registerafter(function func)

+


+

Registers a callback function to run immediately after each frame gets emulated. It runs at a similar time as (and slightly before) gui.register callbacks, except unlike with gui.register it doesn't also get called again whenever the screen gets redrawn. Similar caveats as those mentioned in emu.registerbefore apply.

+


+

emu.registerexit(function func)

+


+

Registers a callback function that runs when the script stops. Whether the script stops on its own or the user tells it to stop, or even if the script crashes or the user tries to close the emulator, FCEUX will try to run whatever Lua code you put in here first. So if you want to make sure some code runs that cleans up some external resources or saves your progress to a file or just says some last words, you could put it here. (Of course, a forceful termination of the application or a crash from inside the registered exit function will still prevent the code from running.)

+


+

Suppose you write a script that registers an exit function and then enters an infinite loop. If the user clicks "Stop" your script will be forcefully stopped, but then it will start running its exit function. If your exit function enters an infinite loop too, then the user will have to click "Stop" a second time to really stop your script. That would be annoying. So try to avoid doing too much inside the exit function.

+


+

Note that restarting a script counts as stopping it and then starting it again, so doing so (either by clicking "Restart" or by editing the script while it is running) will trigger the callback. Note also that returning from a script generally does NOT count as stopping (because your script is still running or waiting to run its callback functions and thus does not stop... see here for more information), even if the exit callback is the only one you have registered. 

+


+

bool emu.addgamegenie(string str)

+


+

Adds a Game Genie code to the Cheats menu. Returns false and an error message if the code can't be decoded. Returns false if the code couldn't be added. Returns true if the code already existed, or if it was added.

+


+

Usage: emu.addgamegenie("NUTANT")

+


+

Note that the Cheats Dialog Box won't show the code unless you close and reopen it.

+


+

bool emu.delgamegenie(string str)

+


+

Removes a Game Genie code from the Cheats menu. Returns false and an error message if the code can't be decoded. Returns false if the code couldn't be deleted. Returns true if the code didn't exist, or if it was deleted.

+


+

Usage: emu.delgamegenie("NUTANT")

+


+

Note that the Cheats Dialog Box won't show the code unless you close and reopen it.

+


+

emu.print(string str)

+


+

Puts a message into the Output Console area of the Lua Script control window. Useful for displaying usage instructions to the user when a script gets run.

+


+

emu.getscreenpixel(int x, int y, bool getemuscreen)

+


+

Returns the separate RGB components of the given screen pixel, and the palette. Can be 0-255 by 0-239, but NTSC only displays 0-255 x 8-231 of it. If getemuscreen is false, this gets background colors from either the screen pixel or the LUA pixels set, but LUA data may not match the information used to put the data to the screen. If getemuscreen is true, this gets background colors from anything behind an LUA screen element.

+


+

Usage is local r,g,b,palette = emu.getscreenpixel(5, 5, false) to retrieve the current red/green/blue colors and palette value of the pixel at 5x5.

+


+

Palette value can be 0-63, or 254 if there was an error.

+


+

You can avoid getting LUA data by putting the data into a function, and feeding the function name to emu.registerbefore.

+


+


+

FCEU library

+


+

The FCEU library is the same as the emu library. It is left in for backwards compatibility. However, the emu library is preferred.

+


+


+

ROM Library

+


+

rom.readbyte(int address)

+

rom.readbyteunsigned(int address)

+


+

Get an unsigned byte from the actual ROM file at the given address.  

+


+

This includes the header! It's the same as opening the file in a hex-editor.

+


+

rom.readbytesigned(int address)

+


+

Get a signed byte from the actual ROM file at the given address. Returns a byte that is signed.

+


+

This includes the header! It's the same as opening the file in a hex-editor.

+


+

rom.writebyte()

+


+

Write the value to the ROM at the given address. The value is modded with 256 before writing (so writing 257 will actually write 1). Negative values allowed.

+


+

Editing the header is not available.

+


+

Memory Library

+


+

memory.readbyte(int address)

+

memory.readbyteunsigned(int address)

+


+

Get an unsigned byte from the RAM at the given address. Returns a byte regardless of emulator. The byte will always be positive.

+


+

memory.readbyterange(int address, int length)

+


+

Get a length bytes starting at the given address and return it as a string. Convert to table to access the individual bytes.

+


+

memory.readbytesigned(int address)

+


+

Get a signed byte from the RAM at the given address. Returns a byte regardless of emulator. The most significant bit will serve as the sign.

+


+

memory.readword(int addressLow, [int addressHigh])

+

memory.readwordunsigned(int addressLow, [int addressHigh])

+


+

Get an unsigned word from the RAM at the given address. Returns a 16-bit value regardless of emulator. The value will always be positive.

+

If you only provide a single parameter (addressLow), the function treats it as address of little-endian word. if you provide two parameters, the function reads the low byte from addressLow and the high byte from addressHigh, so you can use it in games which like to store their variables in separate form (a lot of NES games do).

+


+

memory.readwordsigned(int addressLow, [int addressHigh])

+


+

The same as above, except the returned value is signed, i.e. its most significant bit will serve as the sign.

+


+

memory.writebyte(int address, int value)

+


+

Write the value to the RAM at the given address. The value is modded with 256 before writing (so writing 257 will actually write 1). Negative values allowed.

+


+

int memory.getregister(cpuregistername)

+


+

Returns the current value of the given hardware register.

+

For example, memory.getregister("pc") will return the main CPU's current Program Counter.

+


+

Valid registers are: "a", "x", "y", "s", "p", and "pc".

+


+

memory.setregister(string cpuregistername, int value)

+


+

Sets the current value of the given hardware register.

+

For example, memory.setregister("pc",0x200) will change the main CPU's current Program Counter to 0x200.

+


+

Valid registers are: "a", "x", "y", "s", "p", and "pc".

+


+

You had better know exactly what you're doing or you're probably just going to crash the game if you try to use this function. That applies to the other memory.write functions as well, but to a lesser extent. 

+


+

memory.register(int address, [int size,] function func)

+

memory.registerwrite(int address, [int size,] function func)

+


+

Registers a function to be called immediately whenever the given memory address range is written to.

+


+

address is the address in CPU address space (0x0000 - 0xFFFF).

+


+

size is the number of bytes to "watch". For example, if size is 100 and address is 0x0200, then you will register the function across all 100 bytes from 0x0200 to 0x0263. A write to any of those bytes will trigger the function. Having callbacks on a large range of memory addresses can be expensive, so try to use the smallest range that's necessary for whatever it is you're trying to do. If you don't specify any size then it defaults to 1.

+


+

The callback function will receive two arguments, (address, size) indicating what write operation triggered the callback. If you don't care about that extra information then you can ignore it and define your callback function to not take any arguments. The value that was written is NOT passed into the callback function, but you can easily use any of the memory.read functions to retrieve it.

+


+

You may use a memory.write function from inside the callback to change the value that just got written. However, keep in mind that doing so will trigger your callback again, so you must have a "base case" such as checking to make sure that the value is not already what you want it to be before writing it. Another, more drastic option is to de-register the current callback before performing the write.

+


+

If func is nil that means to de-register any memory write callbacks that the current script has already registered on the given range of bytes.

+


+

memory.registerexec(int address, [int size,] function func)

+

memory.registerrun(int address, [int size,] function func)

+

memory.registerexecute(int address, [int size,] function func)

+


+

Registers a function to be called immediately whenever the emulated system runs code located in the given memory address range.

+


+

Since "address" is the address in CPU address space (0x0000 - 0xFFFF), this doesn't take ROM banking into account, so the callback will be called for any bank, and in some cases you'll have to check current bank in your callback function.

+


+

The information about memory.register applies to this function as well.

+


+
+

Example of custom breakpoint:

-


-

function CounterBreak()

-

ObjCtr = memory.getregister("y")

-

if ObjCtr > 0x16 then

-

gui.text(1, 9, string.format("%02X",ObjCtr))

-

emu.pause() -- or debugger.hitbreakpoint()

-

end

-

end

-

memory.registerexecute(0x863C, CounterBreak);

-
+ + +
+

Example of custom breakpoint:

+


+

function CounterBreak()

+

ObjCtr = memory.getregister("y")

+

if ObjCtr > 0x16 then

+

gui.text(1, 9, string.format("%02X",ObjCtr))

+

emu.pause() -- or debugger.hitbreakpoint()

+

end

+

end

+

memory.registerexecute(0x863C, CounterBreak);

+
-


-


-

Debugger Library

-


-

debugger.hitbreakpoint()

-


-

Simulates a breakpoint hit, pauses emulation and brings up the Debugger window. Use this function in your handlers of custom breakpoints.

-


-

int debugger.getcyclescount()

-


-

Returns an integer value representing the number of CPU cycles elapsed since the poweron or since the last reset of the cycles counter.

-


-

int debugger.getinstructionscount()

-


-

Returns an integer value representing the number of CPU instructions executed since the poweron or since the last reset of the instructions counter.

-


-

debugger.resetcyclescount()

-


-

Resets the cycles counter.

-


-

debugger.resetinstructionscount()

-


-

Resets the instructions counter.

-


-


-

Joypad Library

-


-

table joypad.get(int player)

-

table joypad.read(int player)

-


-

Returns a table of every game button, where each entry is true if that button is currently held (as of the last time the emulation checked), or false if it is not held. This takes keyboard inputs, not Lua. The table keys look like this (case sensitive):

-


-

up, down, left, right, A, B, start, select

-


-

Where a Lua truthvalue true means that the button is set, false means the button is unset. Note that only "false" and "nil" are considered a false value by Lua.  Anything else is true, even the number 0.

-


-

joypad.read left in for backwards compatibility with older versions of FCEU/FCEUX.

-


-

table joypad.getimmediate(int player)

-

table joypad.readimmediate(int player)

-


-

Returns a table of every game button, where each entry is true if that button is held at the moment of calling the function, or false if it is not held. This function polls keyboard input immediately, allowing Lua to interact with user even when emulator is paused.

-


-

As of FCEUX 2.2.0, the function only works in Windows. In Linux this function will return nil.

-


-

table joypad.getdown(int player)

-

table joypad.readdown(int player)

-


-

Returns a table of only the game buttons that are currently held. Each entry is true if that button is currently held (as of the last time the emulation checked), or nil if it is not held.

-


-

table joypad.getup(int player)

-

table joypad.readup(int player)

-


-

Returns a table of only the game buttons that are not currently held. Each entry is nil if that button is currently held (as of the last time the emulation checked), or false if it is not held.

-


-

joypad.set(int player, table input)

-

joypad.write(int player, table input)

-


-

Set the inputs for the given player. Table keys look like this (case sensitive):

-


-

up, down, left, right, A, B, start, select

-


-

There are 4 possible values: true, false, nil, and "invert".

-

true    - Forces the button on

-

false   - Forces the button off

-

nil     - User's button press goes through unchanged

-

"invert"- Reverses the user's button press

-


-

Any string works in place of "invert".  It is suggested as a convention to use "invert" for readability, but strings like "inv", "Weird switchy mechanism", "", or "true or false" works as well as "invert".

-


-

nil and "invert" exists so the script can control individual buttons of the controller without entirely blocking the user from having any control. Perhaps there is a process which can be automated by the script, like an optimal firing pattern, but the user still needs some manual control, such as moving the character around.

-


-

joypad.write left in for backwards compatibility with older versions of FCEU/FCEUX.

-


-


-

Zapper Library

-


-

table zapper.read()

-


-

Returns the zapper data

-

When no movie is loaded this input is the same as the internal mouse input (which is used to generate zapper input, as well as the arkanoid paddle).

-


-

When a movie is playing, it returns the zapper data in the movie code.

-


-

The return table consists of 3 values: x, y, and fire.  x and y are the x,y coordinates of the zapper target in terms of pixels.  fire represents the zapper firing.  0 = not firing, 1 = firing

-


-

zapper.set(table input)

-


-

Sets the zapper input state.

-


-

Taple entries (nil or -1 to leave unaffected):

-

x    - Forces the X position

-

y    - Forces the Y position

-

fire - Forces trigger (true/1 on, false/0 off)

-


-


-

Note: The zapper is always controller 2 on the NES so there is no player argument to these functions.

-


-


-

Input Library

-


-

table input.get()

-

table input.read()

-


-

Reads input from keyboard and mouse. Returns pressed keys and the position of mouse in pixels on game screen.  The function returns a table with at least two properties; table.xmouse and table.ymouse.  Additionally any of these keys will be set to true if they were held at the time of executing this function:

-

leftclick, rightclick, middleclick, capslock, numlock, scrolllock, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, F1, F2, F3, F4, F5, F6,  F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, backspace, tab, enter, shift, control, alt, pause, escape, space, pageup, pagedown, end, home, left, up, right, down, numpad0, numpad1, numpad2, numpad3, numpad4, numpad5, numpad6, numpad7, numpad8, numpad9, numpad*, insert, delete, numpad+, numpad-, numpad., numpad/, semicolon, plus, minus, comma, period, slash, backslash, tilde, quote, leftbracket, rightbracket.

-


-

string input.popup

-

Alias: gui.popup

-


-

Requests input from the user using a multiple-option message box. See gui.popup for complete usage and returns.

-


-


-

Savestate Library

-


-

object savestate.object(int slot = nil)

-


-

Create a new savestate object. Optionally you can save the current state to one of the predefined slots(1-10) using the range 1-9 for slots 1-9, and 10 for 0, QWERTY style. Using no number will create an "anonymous" savestate.

-

Note that this does not actually save the current state! You need to create this value and pass it on to the load and save functions in order to save it.

-


-

Anonymous savestates are temporary, memory only states. You can make them persistent by calling memory.persistent(state). Persistent anonymous states are deleted from disk once the script exits.

-


-

object savestate.create(int slot = nil)

-


-

savestate.create is identical to savestate.object, except for the numbering for predefined slots(1-10, 1 refers to slot 0, 2-10 refer to 1-9). It's being left in for compatibility with older scripts, and potentially for platforms with different internal predefined slot numbering.

-


-

savestate.save(object savestate)

-


-

Save the current state object to the given savestate. The argument is the result of savestate.create(). You can load this state back up by calling savestate.load(savestate) on the same object.

-


-

savestate.load(object savestate)

-


-

Load the the given state. The argument is the result of savestate.create() and has been passed to savestate.save() at least once.

-


-

If this savestate is not persistent and not one of the predefined states, the state will be deleted after loading.

-


-

savestate.persist(object savestate)

-


-

Set the given savestate to be persistent. It will not be deleted when you load this state but at the exit of this script instead, unless it's one of the predefined states.  If it is one of the predefined savestates it will be saved as a file on disk.

-


-

savestate.registersave(function func)

-


-

Registers a callback function that runs whenever the user saves a state. This won't actually be called when the script itself makes a savestate, so none of those endless loops due to a misplaced savestate.save.

-


-

As with other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. Upon registering a second callback, the first is kicked out to make room for the second. In this case, it will return the first function instead of nil, letting you know what was kicked out. Registering nil will clear the previously-registered callback.

-


-

savestate.registerload(function func)

-


-

Registers a callback function that runs whenever the user loads a previously saved state. It's not called when the script itself loads a previous state, so don't worry about your script interrupting itself just because it's loading something.

-


-

The state's data is loaded before this function runs, so you can read the RAM immediately after the user loads a state, or check the new framecount. Particularly useful if you want to update lua's display right away instead of showing junk from before the loadstate.

-


-

savestate.loadscriptdata(int location)

-


-

Accuracy not yet confirmed.

-


-

Intended Function, according to snes9x LUA documentation:

-

Returns the data associated with the given savestate (data that was earlier returned by a registered save callback) without actually loading the rest of that savestate or calling any callbacks. location should be a save slot number.

-


-


-

Movie Library

-


-

bool movie.play(string filename, [bool read_only, [int pauseframe]])

-

bool movie.playback(...)

-

bool movie.load(...)

-


-

Loads and plays a movie from the directory relative to the Lua script or from the absolute path. If read_only is true, the movie will be loaded in read-only mode. The default is read+write.

-


-

A pauseframe can be specified, which controls which frame will auto-pause the movie. By default, this is off. A true value is returned if the movie loaded correctly.

-


-

bool movie.record(string filename, [int save_type, [string author]])

-

bool movie.save(...)

-


-

Starts recording a movie, using the filename, relative to the Lua script.

-


-

An optional save_type can be specified. If set to 0 (default), it will record from a power on state, and automatically do so. This is the recommended setting for creating movies. This can also be set to 1 for savestate or 2 for saveram movies.

-


-

A third parameter specifies an author string. If included, it will be recorded into the movie file.

-


-

bool movie.active()

-


-

Returns true if a movie is currently loaded and false otherwise.  (This should be used to guard against Lua errors when attempting to retrieve movie information).

-


-

int movie.framecount()

-


-

Returns the current frame count. (Has the same affect as emu.framecount)

-


-

string movie.mode()

-


-

Returns the current state of movie playback. Returns one of the following:

-


-

- "record"

-

- "playback"

-

- "finished"

-

- "taseditor"

-

- nil

-


-

movie.rerecordcounting(bool counting)

-


-

Turn the rerecord counter on or off. Allows you to do some brute forcing without inflating the rerecord count.

-


-

movie.stop()

-

movie.close()

-


-

Stops movie playback. If no movie is loaded, it throws a Lua error.

-


-

int movie.length()

-


-

Returns the total number of frames of the current movie. Throws a Lua error if no movie is loaded.

-


-

string movie.name()

-

string movie.getname()

-


-

Returns the filename of the current movie with path. Throws a Lua error if no movie is loaded.

-


-

movie.getfilename()

-


-

Returns the filename of the current movie with no path. Throws a Lua error if no movie is loaded.

-


-

movie.rerecordcount()

-


-

Returns the rerecord count of the current movie. Throws a Lua error if no movie is loaded.

-


-

movie.replay()

-

movie.playbeginning()

-


-

Performs the Play from Beginning function. Movie mode is switched to read-only and the movie loaded will begin playback from frame 1.

-


-

If no movie is loaded, no error is thrown and no message appears on screen.

-


-

bool movie.readonly()

-

bool movie.getreadonly()

-

Alias: emu.getreadonly

-


-

FCEUX keeps the read-only status even without a movie loaded.

-


-

Returns whether the emulator is in read-only state.  

-


-

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

-


-

movie.setreadonly(bool state)

-

Alias: emu.setreadonly

-


-

FCEUX keeps the read-only status even without a movie loaded.

-


-

Sets the read-only status to read-only if argument is true and read+write if false.

-

Note: This might result in an error if the medium of the movie file is  not writeable (such as in an archive file).

-


-

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

-


-

bool movie.recording()

-


-

Returns true if there is a movie loaded and in record mode.

-


-

bool movie.playing()

-


-

Returns true if there is a movie loaded and in play mode.

-


-

bool movie.ispoweron()

-


-

Returns true if the movie recording or loaded started from 'Start'.

-

Returns false if the movie uses a save state.

-

Opposite of movie.isfromsavestate()

-


-

bool movie.isfromsavestate()

-


-

Returns true if the movie recording or loaded started from 'Now'.

-

Returns false if the movie was recorded from a reset.

-

Opposite of movie.ispoweron()

-


-

string movie.name()

-


-

If a movie is loaded it returns the name of the movie, else it throws an error.

-


-

bool movie.readonly()

-


-

Returns the state of read-only. True if in playback mode, false if in record mode.

-


-


-

GUI Library

-


-

gui.pixel(int x, int y, type color)

-

gui.drawpixel(int x, int y, type color)

-

gui.setpixel(int x, int y, type color)

-

gui.writepixel(int x, int y, type color)

-


-

Draw one pixel of a given color at the given position on the screen. See drawing notes and color notes at the bottom of the page.  

-


-

gui.getpixel(int x, int y)

-


-

Returns the separate RGBA components of the given pixel set by gui.pixel. This only gets LUA pixels set, not background colors.

-


-

Usage is local r,g,b,a = gui.getpixel(5, 5) to retrieve the current red/green/blue/alpha values of the LUA pixel at 5x5.

-


-

See emu.getscreenpixel() for an emulator screen variant.

-


-

gui.line(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

-

gui.drawline(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

-


-

Draws a line between the two points. The x1,y1 coordinate specifies one end of the line segment, and the x2,y2 coordinate specifies the other end. If skipfirst is true then this function will not draw anything at the pixel x1,y1, otherwise it will. skipfirst is optional and defaults to false. The default color for the line is solid white, but you may optionally override that using a color of your choice. See also drawing notes and color notes at the bottom of the page.

-


-

gui.box(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-

gui.drawbox(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-

gui.rect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-

gui.drawrect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-


-

Draws a rectangle between the given coordinates of the emulator screen for one frame. The x1,y1 coordinate specifies any corner of the rectangle (preferably the top-left corner), and the x2,y2 coordinate specifies the opposite corner.

-


-

The default color for the box is transparent white with a solid white outline, but you may optionally override those using colors of your choice. Also see drawing notes and color notes.

-


-

gui.text(int x, int y, string str [, textcolor [, backcolor]])

-

gui.drawtext(int x, int y, string str [, textcolor [, backcolor]])

-


-

Draws a given string at the given position. textcolor and backcolor are optional. See 'on colors' at the end of this page for information. Using nil as the input or not including an optional field will make it use the default.

-


-

gui.parsecolor(color)

-


-

Returns the separate RGBA components of the given color.

-

For example, you can say local r,g,b,a = gui.parsecolor('orange') to retrieve the red/green/blue values of the preset color orange. (You could also omit the a in cases like this.) This uses the same conversion method that FCEUX uses internally to support the different representations of colors that the GUI library uses. Overriding this function will not change how FCEUX interprets color values, however.

-


-

gui.savescreenshot()

-

Makes a screenshot of the FCEUX emulated screen, and saves it to the appropriate folder. Performs identically to pressing the Screenshot hotkey.

-


-

gui.savescreenshotas(string name)

-

Makes a screenshot of the FCEUX emulated screen, and saves it to the appropriate folder. However, this one receives a file name for the screenshot.

-

-

string gui.gdscreenshot(bool getemuscreen)

-


-

Takes a screen shot of the image and returns it in the form of a string which can be imported by the gd library using the gd.createFromGdStr() function.

-


-

This function is provided so as to allow FCEUX to not carry a copy of the gd library itself. If you want raw RGB32 access, skip the first 11 bytes (header) and then read pixels as Alpha (always 0), Red, Green, Blue, left to right then top to bottom, range is 0-255 for all colors.

-


-

If getemuscreen is false, this gets background colors from either the screen pixel or the LUA pixels set, but LUA data may not match the information used to put the data to the screen. If getemuscreen is true, this gets background colors from anything behind an LUA screen element.

-


-

Warning: Storing screen shots in memory is not recommended. Memory usage will blow up pretty quick. One screen shot string eats around 230 KB of RAM.

-


-

gui.gdoverlay([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

-

gui.image([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

-

gui.drawimage([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

-


-

Draws an image on the screen. gdimage must be in truecolor gd string format.

-


-

Transparency is fully supported. Also, if alphamul is specified then it will modulate the transparency of the image even if it's originally fully opaque. (alphamul=1.0 is normal, alphamul=0.5 is doubly transparent, alphamul=3.0 is triply opaque, etc.)

-


-

dx,dy determines the top-left corner of where the image should draw. If they are omitted, the image will draw starting at the top-left corner of the screen.

-


-

gui.gdoverlay is an actual drawing function (like gui.box and friends) and thus must be called every frame, preferably inside a gui.register'd function, if you want it to appear as a persistent image onscreen.

-


-

Here is an example that loads a PNG from file, converts it to gd string format, and draws it once on the screen:

-

local gdstr = gd.createFromPng("myimage.png"):gdStr()

-

gui.gdoverlay(gdstr)

-


-

gui.opacity(int alpha)

-


-

Scales the transparency of subsequent draw calls. An alpha of 0.0 means completely transparent, and an alpha of 1.0 means completely unchanged (opaque). Non-integer values are supported and meaningful, as are values greater than 1.0. It is not necessary to use this function (or the less-recommended gui.transparency) to perform drawing with transparency, because you can provide an alpha value in the color argument of each draw call. However, it can sometimes be convenient to be able to globally modify the drawing transparency.

-


-

gui.transparency(int trans)

-


-

Scales the transparency of subsequent draw calls. Exactly the same as gui.opacity, except the range is different: A trans of 4.0 means completely transparent, and a trans of 0.0 means completely unchanged (opaque).

-


-

function gui.register(function func)

-


-

Register a function to be called between a frame being prepared for displaying on your screen and it actually happening. Used when that 1 frame delay for rendering is not acceptable.

-


-

string gui.popup(string message [, string type = "ok" [, string icon = "message"]])

-

string input.popup(string message [, string type = "yesno" [, string icon = "question"]])

-


-

Brings up a modal popup dialog box (everything stops until the user dismisses it). The box displays the message tostring(msg). This function returns the name of the button the user clicked on (as a string).

-


-

type determines which buttons are on the dialog box, and it can be one of the following: 'ok', 'yesno', 'yesnocancel', 'okcancel', 'abortretryignore'.

-

type defaults to 'ok' for gui.popup, or to 'yesno' for input.popup.

-


-

icon indicates the purpose of the dialog box (or more specifically it dictates which title and icon is displayed in the box), and it can be one of the following: 'message', 'question', 'warning', 'error'.

-

icon defaults to 'message' for gui.popup, or to 'question' for input.popup.

-


-

Try to avoid using this function much if at all, because modal dialog boxes can be irritating.

-


-

Linux users might want to install xmessage to perform the work. Otherwise the dialog will appear on the shell and that's less noticeable.

-


-


-

Sound Library

-


-

table sound.get()

-


-

Returns current state of PSG channels in big array.

-


-

table:

-

{

-

 rp2a03:

-

 {

-

   square1:

-

   {

-

     volume, -- 0.0-1.0

-

     frequency, -- in hertz

-

     midikey, -- 0-127

-

     duty, -- 0:12.5% 1:25% 2:50% 3:75%

-

     regs: -- raw register values

-

     {

-

       frequency -- raw freq register value

-

     }

-

   },

-

   square2:

-

   {

-

     volume, -- 0.0-1.0

-

     frequency, -- in hertz

-

     midikey, -- 0-127

-

     duty, -- 0:12.5% 1:25% 2:50% 3:75%

-

     regs: -- raw register values

-

     {

-

       frequency -- raw freq register value

-

     }

-

   },

-

   triangle:

-

   {

-

     volume, -- 0.0-1.0

-

     frequency, -- in hertz (correct?)

-

     midikey, -- 0-127 (correct?)

-

     regs: -- raw register values

-

     {

-

       frequency -- raw freq register value

-

     }

-

   },

-

   noise:

-

   {

-

     volume, -- 0.0-1.0

-

       short, -- true or false

-

     frequency, -- in hertz (correct?)

-

     midikey, -- 0-127 (correct?)

-

     regs: -- raw register values

-

     {

-

       frequency -- raw freq register value

-

     }

-

   },

-

   dpcm:

-

   {

-

     volume, -- 0.0-1.0

-

     frequency, -- in hertz (correct?)

-

     midikey, -- 0-127 (correct?)

-

     dmcaddress, -- start position of the sample

-

     dmcsize, -- size of the sample, in bytes

-

     dmcloop, -- true:looped sample, false:oneshot

-

     dmcseed, -- InitialRawDALatch

-

     regs: -- raw register values

-

     {

-

       frequency -- raw freq register value

-

     }

-

   }

-

 }

-

}

-


-


-

TAS Editor Library

-


-

taseditor.registerauto(function func)

-

taseditor.registermanual(function func)

-

bool taseditor.engaged()

-

bool taseditor.markedframe(int frame)

-

int taseditor.getmarker(int frame)

-

int taseditor.setmarker(int frame)

-

taseditor.clearmarker(int frame)

-

string taseditor.getnote(int index)

-

taseditor.setnote(int index, string newtext)

-

int taseditor.getcurrentbranch()

-

string taseditor.getrecordermode()

-

int taseditor.getsuperimpose()

-

int taseditor.getlostplayback()

-

int taseditor.getplaybacktarget()

-

taseditor.setplayback(int frame)

-

taseditor.stopseeking()

-

taseditor.getselection()

-

taseditor.setselection()

-

int taseditor.getinput(int frame, int joypad)

-

taseditor.submitinputchange(int frame, int joypad, int input)

-

taseditor.submitinsertframes(int frame, int number)

-

taseditor.submitdeleteframes(int frame, int number)

-

int taseditor.applyinputchanges([string name])

-

taseditor.clearinputchanges()

-


-

For full description of these functions refer to TAS Editor Manual.

-


-


-

Bitwise Operations

-


-

The following bit functions were added to FCEUX internally to compensate for Lua's lack of them. But it also supports all operations from LuaBitOp module, since it is also embedded in FCEUX.

-


-

int AND(int n1, int n2, ..., int nn)

-


-

Binary logical AND of all the given integers.

-


-

int OR(int n1, int n2, ..., int nn)

-


-

Binary logical OR of all the given integers.

-


-

int XOR(int n1, int n2, ..., int nn)

-


-

Binary logical XOR of all the given integers.

-


-

int BIT(int n1, int n2, ..., int nn)

-


-

Returns an integer with the given bits turned on. Parameters should be smaller than 31.

-


-

Appendix

-


-

On drawing

-


-

A general warning about drawing is that it is always one frame behind unless you use gui.register. This is because you tell the emulator to paint something but it will actually paint it when generating the image for the next frame. So you see your painting, except it will be on the image of the next frame. You can prevent this with gui.register because it gives you a quick chance to paint before blitting.

-


-

Dimensions & color depths you can paint in:

-

--320x239, 8bit color (confirm?)

-

256x224, 8bit color (confirm?)

-


-

On colors

-


-

Colors can be of a few types.

-

Int: use the a formula to compose the color as a number (depends on color depth)

-

String: Can either be a HTML colors, simple colors, or internal palette colors.

-

HTML string: "#rrggbb" ("#228844") or #rrggbbaa if alpha is supported.

-

Simple colors: "clear", "red", "green", "blue", "white", "black", "gray", "grey", "orange", "yellow", "green", "teal", "cyan", "purple", "magenta".

-

Array: Example: {255,112,48,96} means {red=255, green=112, blue=48, alpha=96}

-

Table: Example: {r=255,g=112,b=48,a=96} means {red=255, green=112, blue=48, alpha=96}

-

Palette: Example: "P00" for Palette 00. "P3F" for palette 3F. P40-P7F are for LUA.

-


-

For transparancy use "clear".

-


+


+


+

Debugger Library

+


+

debugger.hitbreakpoint()

+


+

Simulates a breakpoint hit, pauses emulation and brings up the Debugger window. Use this function in your handlers of custom breakpoints.

+


+

int debugger.getcyclescount()

+


+

Returns an integer value representing the number of CPU cycles elapsed since the poweron or since the last reset of the cycles counter.

+


+

int debugger.getinstructionscount()

+


+

Returns an integer value representing the number of CPU instructions executed since the poweron or since the last reset of the instructions counter.

+


+

debugger.resetcyclescount()

+


+

Resets the cycles counter.

+


+

debugger.resetinstructionscount()

+


+

Resets the instructions counter.

+


+


+

Joypad Library

+


+

table joypad.get(int player)

+

table joypad.read(int player)

+


+

Returns a table of every game button, where each entry is true if that button is currently held (as of the last time the emulation checked), or false if it is not held. This takes keyboard inputs, not Lua. The table keys look like this (case sensitive):

+


+

up, down, left, right, A, B, start, select

+


+

Where a Lua truthvalue true means that the button is set, false means the button is unset. Note that only "false" and "nil" are considered a false value by Lua.  Anything else is true, even the number 0.

+


+

joypad.read left in for backwards compatibility with older versions of FCEU/FCEUX.

+


+

table joypad.getimmediate(int player)

+

table joypad.readimmediate(int player)

+


+

Returns a table of every game button, where each entry is true if that button is held at the moment of calling the function, or false if it is not held. This function polls keyboard input immediately, allowing Lua to interact with user even when emulator is paused.

+


+

As of FCEUX 2.2.0, the function only works in Windows. In Linux this function will return nil.

+


+

table joypad.getdown(int player)

+

table joypad.readdown(int player)

+


+

Returns a table of only the game buttons that are currently held. Each entry is true if that button is currently held (as of the last time the emulation checked), or nil if it is not held.

+


+

table joypad.getup(int player)

+

table joypad.readup(int player)

+


+

Returns a table of only the game buttons that are not currently held. Each entry is nil if that button is currently held (as of the last time the emulation checked), or false if it is not held.

+


+

joypad.set(int player, table input)

+

joypad.write(int player, table input)

+


+

Set the inputs for the given player. Table keys look like this (case sensitive):

+


+

up, down, left, right, A, B, start, select

+


+

There are 4 possible values: true, false, nil, and "invert".

+

true    - Forces the button on

+

false   - Forces the button off

+

nil     - User's button press goes through unchanged

+

"invert"- Reverses the user's button press

+


+

Any string works in place of "invert".  It is suggested as a convention to use "invert" for readability, but strings like "inv", "Weird switchy mechanism", "", or "true or false" works as well as "invert".

+


+

nil and "invert" exists so the script can control individual buttons of the controller without entirely blocking the user from having any control. Perhaps there is a process which can be automated by the script, like an optimal firing pattern, but the user still needs some manual control, such as moving the character around.

+


+

joypad.write left in for backwards compatibility with older versions of FCEU/FCEUX.

+


+


+

Zapper Library

+


+

table zapper.read()

+


+

Returns the zapper data

+

When no movie is loaded this input is the same as the internal mouse input (which is used to generate zapper input, as well as the arkanoid paddle).

+


+

When a movie is playing, it returns the zapper data in the movie code.

+


+

The return table consists of 3 values: x, y, and fire.  x and y are the x,y coordinates of the zapper target in terms of pixels.  fire represents the zapper firing.  0 = not firing, 1 = firing

+


+


+

Note: The zapper is always controller 2 on the NES so there is no player argument to this function.

+


+


+

Input Library

+


+

table input.get()

+

table input.read()

+


+

Reads input from keyboard and mouse. Returns pressed keys and the position of mouse in pixels on game screen.  The function returns a table with at least two properties; table.xmouse and table.ymouse.  Additionally any of these keys will be set to true if they were held at the time of executing this function:

+

leftclick, rightclick, middleclick, capslock, numlock, scrolllock, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, F1, F2, F3, F4, F5, F6,  F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, backspace, tab, enter, shift, control, alt, pause, escape, space, pageup, pagedown, end, home, left, up, right, down, numpad0, numpad1, numpad2, numpad3, numpad4, numpad5, numpad6, numpad7, numpad8, numpad9, numpad*, insert, delete, numpad+, numpad-, numpad., numpad/, semicolon, plus, minus, comma, period, slash, backslash, tilde, quote, leftbracket, rightbracket.

+


+

string input.popup

+

Alias: gui.popup

+


+

Requests input from the user using a multiple-option message box. See gui.popup for complete usage and returns.

+


+


+

Savestate Library

+


+

object savestate.object(int slot = nil)

+


+

Create a new savestate object. Optionally you can save the current state to one of the predefined slots(1-10) using the range 1-9 for slots 1-9, and 10 for 0, QWERTY style. Using no number will create an "anonymous" savestate.

+

Note that this does not actually save the current state! You need to create this value and pass it on to the load and save functions in order to save it.

+


+

Anonymous savestates are temporary, memory only states. You can make them persistent by calling memory.persistent(state). Persistent anonymous states are deleted from disk once the script exits.

+


+

object savestate.create(int slot = nil)

+


+

savestate.create is identical to savestate.object, except for the numbering for predefined slots(1-10, 1 refers to slot 0, 2-10 refer to 1-9). It's being left in for compatibility with older scripts, and potentially for platforms with different internal predefined slot numbering.

+


+

savestate.save(object savestate)

+


+

Save the current state object to the given savestate. The argument is the result of savestate.create(). You can load this state back up by calling savestate.load(savestate) on the same object.

+


+

savestate.load(object savestate)

+


+

Load the the given state. The argument is the result of savestate.create() and has been passed to savestate.save() at least once.

+


+

If this savestate is not persistent and not one of the predefined states, the state will be deleted after loading.

+


+

savestate.persist(object savestate)

+


+

Set the given savestate to be persistent. It will not be deleted when you load this state but at the exit of this script instead, unless it's one of the predefined states.  If it is one of the predefined savestates it will be saved as a file on disk.

+


+

savestate.registersave(function func)

+


+

Registers a callback function that runs whenever the user saves a state. This won't actually be called when the script itself makes a savestate, so none of those endless loops due to a misplaced savestate.save.

+


+

As with other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. Upon registering a second callback, the first is kicked out to make room for the second. In this case, it will return the first function instead of nil, letting you know what was kicked out. Registering nil will clear the previously-registered callback.

+


+

savestate.registerload(function func)

+


+

Registers a callback function that runs whenever the user loads a previously saved state. It's not called when the script itself loads a previous state, so don't worry about your script interrupting itself just because it's loading something.

+


+

The state's data is loaded before this function runs, so you can read the RAM immediately after the user loads a state, or check the new framecount. Particularly useful if you want to update lua's display right away instead of showing junk from before the loadstate.

+


+

savestate.loadscriptdata(int location)

+


+

Accuracy not yet confirmed.

+


+

Intended Function, according to snes9x LUA documentation:

+

Returns the data associated with the given savestate (data that was earlier returned by a registered save callback) without actually loading the rest of that savestate or calling any callbacks. location should be a save slot number.

+


+


+

Movie Library

+


+

bool movie.active()

+


+

Returns true if a movie is currently loaded and false otherwise.  (This should be used to guard against Lua errors when attempting to retrieve movie information).

+


+

int movie.framecount()

+


+

Returns the current frame count. (Has the same affect as emu.framecount)

+


+

string movie.mode()

+


+

Returns the current state of movie playback. Returns one of the following:

+


+

- "record"

+

- "playback"

+

- "finished"

+

- "taseditor"

+

- nil

+


+

movie.rerecordcounting(bool counting)

+


+

Turn the rerecord counter on or off. Allows you to do some brute forcing without inflating the rerecord count.

+


+

movie.stop()

+

movie.close()

+


+

Stops movie playback. If no movie is loaded, it throws a Lua error.

+


+

int movie.length()

+


+

Returns the total number of frames of the current movie. Throws a Lua error if no movie is loaded.

+


+

string movie.name()

+

string movie.getname()

+


+

Returns the filename of the current movie with path. Throws a Lua error if no movie is loaded.

+


+

movie.getfilename()

+


+

Returns the filename of the current movie with no path. Throws a Lua error if no movie is loaded.

+


+

movie.rerecordcount()

+


+

Returns the rerecord count of the current movie. Throws a Lua error if no movie is loaded.

+


+

movie.replay()

+

movie.playbeginning()

+


+

Performs the Play from Beginning function. Movie mode is switched to read-only and the movie loaded will begin playback from frame 1.

+


+

If no movie is loaded, no error is thrown and no message appears on screen.

+


+

bool movie.readonly()

+

bool movie.getreadonly()

+

Alias: emu.getreadonly

+


+

FCEUX keeps the read-only status even without a movie loaded.

+


+

Returns whether the emulator is in read-only state.  

+


+

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

+


+

movie.setreadonly(bool state)

+

Alias: emu.setreadonly

+


+

FCEUX keeps the read-only status even without a movie loaded.

+


+

Sets the read-only status to read-only if argument is true and read+write if false.

+

Note: This might result in an error if the medium of the movie file is  not writeable (such as in an archive file).

+


+

While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.

+


+

bool movie.recording()

+


+

Returns true if there is a movie loaded and in record mode.

+


+

bool movie.playing()

+


+

Returns true if there is a movie loaded and in play mode.

+


+

bool movie.ispoweron()

+


+

Returns true if the movie recording or loaded started from 'Start'.

+

Returns false if the movie uses a save state.

+

Opposite of movie.isfromsavestate()

+


+

bool movie.isfromsavestate()

+


+

Returns true if the movie recording or loaded started from 'Now'.

+

Returns false if the movie was recorded from a reset.

+

Opposite of movie.ispoweron()

+


+

string movie.name()

+


+

If a movie is loaded it returns the name of the movie, else it throws an error.

+


+

bool movie.readonly()

+


+

Returns the state of read-only. True if in playback mode, false if in record mode.

+


+


+

GUI Library

+


+

gui.pixel(int x, int y, type color)

+

gui.drawpixel(int x, int y, type color)

+

gui.setpixel(int x, int y, type color)

+

gui.writepixel(int x, int y, type color)

+


+

Draw one pixel of a given color at the given position on the screen. See drawing notes and color notes at the bottom of the page.  

+


+

gui.getpixel(int x, int y)

+


+

Returns the separate RGBA components of the given pixel set by gui.pixel. This only gets LUA pixels set, not background colors.

+


+

Usage is local r,g,b,a = gui.getpixel(5, 5) to retrieve the current red/green/blue/alpha values of the LUA pixel at 5x5.

+


+

See emu.getscreenpixel() for an emulator screen variant.

+


+

gui.line(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

+

gui.drawline(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

+


+

Draws a line between the two points. The x1,y1 coordinate specifies one end of the line segment, and the x2,y2 coordinate specifies the other end. If skipfirst is true then this function will not draw anything at the pixel x1,y1, otherwise it will. skipfirst is optional and defaults to false. The default color for the line is solid white, but you may optionally override that using a color of your choice. See also drawing notes and color notes at the bottom of the page.

+


+

gui.box(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.drawbox(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.rect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.drawrect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+


+

Draws a rectangle between the given coordinates of the emulator screen for one frame. The x1,y1 coordinate specifies any corner of the rectangle (preferably the top-left corner), and the x2,y2 coordinate specifies the opposite corner.

+


+

The default color for the box is transparent white with a solid white outline, but you may optionally override those using colors of your choice. Also see drawing notes and color notes.

+


+

gui.text(int x, int y, string str [, textcolor [, backcolor]])

+

gui.drawtext(int x, int y, string str [, textcolor [, backcolor]])

+


+

Draws a given string at the given position. textcolor and backcolor are optional. See 'on colors' at the end of this page for information. Using nil as the input or not including an optional field will make it use the default.

+


+

gui.parsecolor(color)

+


+

Returns the separate RGBA components of the given color.

+

For example, you can say local r,g,b,a = gui.parsecolor('orange') to retrieve the red/green/blue values of the preset color orange. (You could also omit the a in cases like this.) This uses the same conversion method that FCEUX uses internally to support the different representations of colors that the GUI library uses. Overriding this function will not change how FCEUX interprets color values, however.

+


+

gui.savescreenshot()

+

Makes a screenshot of the FCEUX emulated screen, and saves it to the appropriate folder. Performs identically to pressing the Screenshot hotkey.

+


+

gui.savescreenshotas(string name)

+

Makes a screenshot of the FCEUX emulated screen, and saves it to the appropriate folder. However, this one receives a file name for the screenshot.

+

 

+

string gui.gdscreenshot()

+


+

Takes a screen shot of the image and returns it in the form of a string which can be imported by the gd library using the gd.createFromGdStr() function.

+


+

This function is provided so as to allow FCEUX to not carry a copy of the gd library itself. If you want raw RGB32 access, skip the first 11 bytes (header) and then read pixels as Alpha (always 0), Red, Green, Blue, left to right then top to bottom, range is 0-255 for all colors.

+


+

Warning: Storing screen shots in memory is not recommended. Memory usage will blow up pretty quick. One screen shot string eats around 230 KB of RAM.

+


+

gui.gdoverlay([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

+

gui.image([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

+

gui.drawimage([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

+


+

Draws an image on the screen. gdimage must be in truecolor gd string format.

+


+

Transparency is fully supported. Also, if alphamul is specified then it will modulate the transparency of the image even if it's originally fully opaque. (alphamul=1.0 is normal, alphamul=0.5 is doubly transparent, alphamul=3.0 is triply opaque, etc.)

+


+

dx,dy determines the top-left corner of where the image should draw. If they are omitted, the image will draw starting at the top-left corner of the screen.

+


+

gui.gdoverlay is an actual drawing function (like gui.box and friends) and thus must be called every frame, preferably inside a gui.register'd function, if you want it to appear as a persistent image onscreen.

+


+

Here is an example that loads a PNG from file, converts it to gd string format, and draws it once on the screen:

+

local gdstr = gd.createFromPng("myimage.png"):gdStr()

+

gui.gdoverlay(gdstr) 

+


+

gui.opacity(int alpha)

+


+

Scales the transparency of subsequent draw calls. An alpha of 0.0 means completely transparent, and an alpha of 1.0 means completely unchanged (opaque). Non-integer values are supported and meaningful, as are values greater than 1.0. It is not necessary to use this function (or the less-recommended gui.transparency) to perform drawing with transparency, because you can provide an alpha value in the color argument of each draw call. However, it can sometimes be convenient to be able to globally modify the drawing transparency. 

+


+

gui.transparency(int trans)

+


+

Scales the transparency of subsequent draw calls. Exactly the same as gui.opacity, except the range is different: A trans of 4.0 means completely transparent, and a trans of 0.0 means completely unchanged (opaque). 

+


+

function gui.register(function func)

+


+

Register a function to be called between a frame being prepared for displaying on your screen and it actually happening. Used when that 1 frame delay for rendering is not acceptable.

+


+

string gui.popup(string message [, string type = "ok" [, string icon = "message"]])

+

string input.popup(string message [, string type = "yesno" [, string icon = "question"]])

+


+

Brings up a modal popup dialog box (everything stops until the user dismisses it). The box displays the message tostring(msg). This function returns the name of the button the user clicked on (as a string).

+


+

type determines which buttons are on the dialog box, and it can be one of the following: 'ok', 'yesno', 'yesnocancel', 'okcancel', 'abortretryignore'.

+

type defaults to 'ok' for gui.popup, or to 'yesno' for input.popup.

+


+

icon indicates the purpose of the dialog box (or more specifically it dictates which title and icon is displayed in the box), and it can be one of the following: 'message', 'question', 'warning', 'error'.

+

icon defaults to 'message' for gui.popup, or to 'question' for input.popup.

+


+

Try to avoid using this function much if at all, because modal dialog boxes can be irritating. 

+


+

Linux users might want to install xmessage to perform the work. Otherwise the dialog will appear on the shell and that's less noticeable.

+


+


+

Sound Library

+


+

table sound.get()

+


+

Returns current state of PSG channels in big array.

+


+

table:

+

{

+

  rp2a03:

+

  {

+

    square1:

+

    {

+

      volume, -- 0.0-1.0

+

      frequency, -- in hertz

+

      midikey, -- 0-127

+

      duty, -- 0:12.5% 1:25% 2:50% 3:75%

+

      regs: -- raw register values

+

      {

+

        frequency -- raw freq register value

+

      }

+

    },

+

    square2:

+

    {

+

      volume, -- 0.0-1.0

+

      frequency, -- in hertz

+

      midikey, -- 0-127

+

      duty, -- 0:12.5% 1:25% 2:50% 3:75%

+

      regs: -- raw register values

+

      {

+

        frequency -- raw freq register value

+

      }

+

    },

+

    triangle:

+

    {

+

      volume, -- 0.0-1.0

+

      frequency, -- in hertz (correct?)

+

      midikey, -- 0-127 (correct?)

+

      regs: -- raw register values

+

      {

+

        frequency -- raw freq register value

+

      }

+

    },

+

    noise:

+

    {

+

      volume, -- 0.0-1.0

+

       short, -- true or false

+

      frequency, -- in hertz (correct?)

+

      midikey, -- 0-127 (correct?)

+

      regs: -- raw register values

+

      {

+

        frequency -- raw freq register value

+

      }

+

    },

+

    dpcm:

+

    {

+

      volume, -- 0.0-1.0

+

      frequency, -- in hertz (correct?)

+

      midikey, -- 0-127 (correct?)

+

      dmcaddress, -- start position of the sample

+

      dmcsize, -- size of the sample, in bytes

+

      dmcloop, -- true:looped sample, false:oneshot

+

      dmcseed, -- InitialRawDALatch

+

      regs: -- raw register values

+

      {

+

        frequency -- raw freq register value

+

      }

+

    }

+

  }

+

}

+


+


+

TAS Editor Library

+


+

taseditor.registerauto(function func)

+

taseditor.registermanual(function func)

+

bool taseditor.engaged()

+

bool taseditor.markedframe(int frame)

+

int taseditor.getmarker(int frame)

+

int taseditor.setmarker(int frame)

+

taseditor.clearmarker(int frame)

+

string taseditor.getnote(int index)

+

taseditor.setnote(int index, string newtext)

+

int taseditor.getcurrentbranch()

+

string taseditor.getrecordermode()

+

int taseditor.getsuperimpose()

+

int taseditor.getlostplayback()

+

int taseditor.getplaybacktarget()

+

taseditor.setplayback(int frame)

+

taseditor.stopseeking()

+

taseditor.getselection()

+

taseditor.setselection()

+

int taseditor.getinput(int frame, int joypad)

+

taseditor.submitinputchange(int frame, int joypad, int input)

+

taseditor.submitinsertframes(int frame, int number)

+

taseditor.submitdeleteframes(int frame, int number)

+

int taseditor.applyinputchanges([string name])

+

taseditor.clearinputchanges()

+


+

For full description of these functions refer to TAS Editor Manual.

+


+


+

Bitwise Operations

+


+

The following bit functions were added to FCEUX internally to compensate for Lua's lack of them. But it also supports all operations from LuaBitOp module, since it is also embedded in FCEUX.

+


+

int AND(int n1, int n2, ..., int nn)

+


+

Binary logical AND of all the given integers.

+


+

int OR(int n1, int n2, ..., int nn)

+


+

Binary logical OR of all the given integers.

+


+

int XOR(int n1, int n2, ..., int nn)

+


+

Binary logical XOR of all the given integers. 

+


+

int BIT(int n1, int n2, ..., int nn)

+


+

Returns an integer with the given bits turned on. Parameters should be smaller than 31.

+


+

Appendix

+


+

On drawing

+


+

A general warning about drawing is that it is always one frame behind unless you use gui.register. This is because you tell the emulator to paint something but it will actually paint it when generating the image for the next frame. So you see your painting, except it will be on the image of the next frame. You can prevent this with gui.register because it gives you a quick chance to paint before blitting.

+


+

Dimensions & color depths you can paint in:

+

--320x239, 8bit color (confirm?)

+

256x224, 8bit color (confirm?)

+


+

On colors

+


+

Colors can be of a few types.

+

Int: use the a formula to compose the color as a number (depends on color depth)

+

String: Can either be a HTML colors, simple colors, or internal palette colors.

+

HTML string: "#rrggbb" ("#228844") or #rrggbbaa if alpha is supported.

+

Simple colors: "clear", "red", "green", "blue", "white", "black", "gray", "grey", "orange", "yellow", "green", "teal", "cyan", "purple", "magenta".

+

Array: Example: {255,112,48,96} means {red=255, green=112, blue=48, alpha=96} 

+

Table: Example: {r=255,g=112,b=48,a=96} means {red=255, green=112, blue=48, alpha=96} 

+

Palette: Example: "P00" for Palette 00. "P3F" for palette 3F. P40-P7F are for LUA.

+


+

For transparancy use "clear".

+


-

Created with the Personal Edition of HelpNDoc: Easily create EPub books

-
- - + + +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + - -
- - diff --git a/web/help/LuaGettingStarted.html b/web/help/LuaGettingStarted.html index 6bb9ddf5..f57cb5d2 100644 --- a/web/help/LuaGettingStarted.html +++ b/web/help/LuaGettingStarted.html @@ -1,107 +1,298 @@ - - + + + + + - Getting Started - - - - - - - - - - + + + + + + + + Getting Started + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Getting Started

- -
- Lua Scripting ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Using Lua scripting

-


-

Lua is built into FCEUX as of 2.1.2, and luapack DLL files are no longer needed in this and later versions.

-


-

To run lua scripts in older versions of FCEUX, you will need the lua pack which can be found here. The .dll files must be unzipped in the same folder as fceux.exe.

-


-

Core Lua Documentation

-


-

If you have never programmed, you will probably want to start by learning the basic of Lua, which is too broad for the scope of this help file.  Try searching on the Internet for "Lua tutorial".  As of this writing, it's official homepage is http://www.lua.org/

-


-

If you are familiar with any programming language you will probably not have too much difficulty adjusting to the syntax and structure of Lua.  You will probably also find useful information on the Internet.

-


-

GUI Frontend

-


-

To use a Lua script, you need to create one in a text editor.  The name of the file created should end in .lua to indicate that it is a Lua script.

-


-

To run a Lua script, choose "Run Lua Script" ***from where***  In the dialog that pops up, click "Browse" and find the file you wish to run.  This will insert the path of this file into the dialog.  You can then click on "Run" to run the script or "Cancel" to return to FCEUX without running the script.

-


-

To end a Lua script, choose "Stop Lua Script" ***from where***.

-


-

FCEUX Lua Basics

-


-

Your script will be constructed according to the rules of Lua, but you will use FCEUX-specific functions to interact with the emulator.  For example, one of the most often-used functions is emu.frameadvance() which will tell the emulator to advance exactly one frame, which is the basic unit of time on an NES.

-


-

In general, your script will probably want to be run until you tell it to stop, so it will look something like this:

-


-

emu.speedmode("normal") -- Set the speed of the emulator

-


-

-- Declare and set variables or functions if needed

-


-

while true do

-

  -- Execute instructions for FCEUX

-

  emu.frameadvance() -- This essentially tells FCEUX to keep running

-

end

-


-

The way instructions are sent to FCEUX is through a set of specially defined functions (and variables) which are called an API, the specification of which follows.

-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Getting Started

+ +
+ +

+

Using Lua scripting

+


+

Lua is built into FCEUX as of 2.1.2, and luapack DLL files are no longer needed in this and later versions.

+


+

To run lua scripts in older versions of FCEUX, you will need the lua pack which can be found here. The .dll files must be unzipped in the same folder as fceux.exe.

+


+

Core Lua Documentation

+


+

If you have never programmed, you will probably want to start by learning the basic of Lua, which is too broad for the scope of this help file.  Try searching on the Internet for "Lua tutorial".  As of this writing, it's official homepage is http://www.lua.org/

+


+

If you are familiar with any programming language you will probably not have too much difficulty adjusting to the syntax and structure of Lua.  You will probably also find useful information on the Internet.

+


+

GUI Frontend

+


+

To use a Lua script, you need to create one in a text editor.  The name of the file created should end in .lua to indicate that it is a Lua script.

+


+

To run a Lua script, choose "Run Lua Script" ***from where***  In the dialog that pops up, click "Browse" and find the file you wish to run.  This will insert the path of this file into the dialog.  You can then click on "Run" to run the script or "Cancel" to return to FCEUX without running the script.

+


+

To end a Lua script, choose "Stop Lua Script" ***from where***.

+


+

FCEUX Lua Basics

+


+

Your script will be constructed according to the rules of Lua, but you will use FCEUX-specific functions to interact with the emulator.  For example, one of the most often-used functions is emu.frameadvance() which will tell the emulator to advance exactly one frame, which is the basic unit of time on an NES.

+


+

In general, your script will probably want to be run until you tell it to stop, so it will look something like this:

+


+

emu.speedmode("normal") -- Set the speed of the emulator

+


+

-- Declare and set variables or functions if needed

+


+

while true do

+

   -- Execute instructions for FCEUX

+

   emu.frameadvance() -- This essentially tells FCEUX to keep running

+

end

+


+

The way instructions are sent to FCEUX is through a set of specially defined functions (and variables) which are called an API, the specification of which follows.

+

+

Created with the Personal Edition of HelpNDoc: Free help authoring environment

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/LuaPerks.html b/web/help/LuaPerks.html index 68bbacf4..d56793a7 100644 --- a/web/help/LuaPerks.html +++ b/web/help/LuaPerks.html @@ -1,123 +1,314 @@ - - + + + + + - LuaPerks - - - - - - - - - - + + + + + + + + LuaPerks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

LuaPerks

- -
- Lua Scripting ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

LuaPerks

-


-

The following Lua libraries are integrated into FCEUX win32-executable (statically linked) and are available for using in your scripts. You can also use any other Lua library by placing its .dll files into FCEUX folder.

-


-


-

IUP library

-


-

IUP (Portable User Interface) is a toolkit for building graphical user interfaces.

-


-

Usage example: \luaScripts\GUI-iup_example.lua

-


-

http://www.tecgraf.puc-rio.br/iup/

-


-


-

IM library

-


-

IM is a toolkit for Digital Imaging. The main goal of the library is to provide a simple API and abstraction of images for applications.

-

File formats supported: TIFF, BMP, PNG, JPEG, GIF and AVI. Image representation includes scientific data types. About a hundred Image Processing operations are available.

-


-

http://www.tecgraf.puc-rio.br/im/

-


-


-

CD library

-


-

Canvas Draw is a graphics library.

-

The library contains functions to support both vector and image applications, and the visualization surface can be either a window or a more abstract surface, such as Image, Clipboard, Metafile, PS, and so on.

-


-

http://www.tecgraf.puc-rio.br/cd/

-


-


-

LuaSocket library

-


-

LuaSocket is a Lua extension library that is composed by two parts: a C core that provides support for the TCP and UDP transport layers, and a set of Lua modules that add support for the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and downloading files) protocols and other functionality commonly needed by applications that deal with the Internet.

-


-

Usage: netplay, local data transmission.

-


-

http://w3.impa.br/~diego/software/luasocket/home.html

-


-


-

WinAPI library

-


-

This module provides basic tools for working with Windows system resources.

-


-

Usage example: \luaScripts\JumpingFCEUXWindow.lua

-


-

https://github.com/stevedonovan/winapi

-


-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free EBook and documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

LuaPerks

+ +
+ +

+

LuaPerks

+


+

The following Lua libraries are integrated into FCEUX win32-executable (statically linked) and are available for using in your scripts. You can also use any other Lua library by placing its .dll files into FCEUX folder.

+


+


+

IUP library

+


+

IUP (Portable User Interface) is a toolkit for building graphical user interfaces.

+


+

Usage example: \luaScripts\GUI-iup_example.lua 

+


+

http://www.tecgraf.puc-rio.br/iup/

+


+


+

IM library

+


+

IM is a toolkit for Digital Imaging. The main goal of the library is to provide a simple API and abstraction of images for applications.

+

File formats supported: TIFF, BMP, PNG, JPEG, GIF and AVI. Image representation includes scientific data types. About a hundred Image Processing operations are available.

+


+

http://www.tecgraf.puc-rio.br/im/

+


+


+

CD library

+


+

Canvas Draw is a graphics library.

+

The library contains functions to support both vector and image applications, and the visualization surface can be either a window or a more abstract surface, such as Image, Clipboard, Metafile, PS, and so on.

+


+

http://www.tecgraf.puc-rio.br/cd/

+


+


+

LuaSocket library

+


+

LuaSocket is a Lua extension library that is composed by two parts: a C core that provides support for the TCP and UDP transport layers, and a set of Lua modules that add support for the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and downloading files) protocols and other functionality commonly needed by applications that deal with the Internet.

+


+

Usage: netplay, local data transmission.

+


+

http://w3.impa.br/~diego/software/luasocket/home.html

+


+


+

WinAPI library

+


+

This module provides basic tools for working with Windows system resources.

+


+

Usage example: \luaScripts\JumpingFCEUXWindow.lua

+


+

https://github.com/stevedonovan/winapi

+


+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create CHM Help documents

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/LuaScripting.html b/web/help/LuaScripting.html index bdf03d1c..aed3a5ff 100644 --- a/web/help/LuaScripting.html +++ b/web/help/LuaScripting.html @@ -1,97 +1,292 @@ - - + + + + + - Lua Scripting - - - - - - - - - - + + + + + + + + Lua Scripting + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Lua Scripting

- -
-
- Previous - - Next - -
-
-
-
- -

-

Lua Scripting

-


-

Lua is a scripting language similar to Perl or Python.  It allows for logical evaluation equivalent to languages like C but in a much more dynamic way that eliminates much of the need to compile programs and worry about low level resource management like deleting objects.  In the context of FCEUX, Lua allows for direct control of the emulator through this logical construct.

-


-

What this means to a non-"programmer" is that you can essentially automate certain tasks in FCEUX, such as holding controller inputs, displaying additional graphical information and saving/loading savestates.

-


-

A bit of previous programming knowledge will be useful in taking advantage of this feature, but it is certainly not a requirement.  Lua is specifically written with the intention of being easier than most languages for anyone to understand and use.

-


-


-

Getting Started

-


-

The basics of Lua scripting, its implementation into FCEUX, and how to get started using Lua.

-


-

Using Lua

-


-

How to use Lua and basic syntax/commands that are useable under FCEUX.

-


-

Lua Functions List

-


-

A list of Lua functions available in FCEUX and a brief description of each.

-


-

LuaPerks

-


-

Additional libraries integrated into FCEUX.

-


-

Lua Bot

-


-

How to use Luau's version of Basic bot.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Free iPhone documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Lua Scripting

+ +
+ +

+

Lua Scripting

+


+

Lua is a scripting language similar to Perl or Python.  It allows for logical evaluation equivalent to languages like C but in a much more dynamic way that eliminates much of the need to compile programs and worry about low level resource management like deleting objects.  In the context of FCEUX, Lua allows for direct control of the emulator through this logical construct.

+


+

What this means to a non-"programmer" is that you can essentially automate certain tasks in FCEUX, such as holding controller inputs, displaying additional graphical information and saving/loading savestates.

+


+

A bit of previous programming knowledge will be useful in taking advantage of this feature, but it is certainly not a requirement.  Lua is specifically written with the intention of being easier than most languages for anyone to understand and use.

+


+


+

Getting Started

+


+

The basics of Lua scripting, its implementation into FCEUX, and how to get started using Lua.

+


+

Using Lua

+


+

How to use Lua and basic syntax/commands that are useable under FCEUX.

+


+

Lua Functions List

+


+

A list of Lua functions available in FCEUX and a brief description of each.

+


+

LuaPerks

+


+

Additional libraries integrated into FCEUX.

+


+

Lua Bot

+


+

How to use Luau's version of Basic bot.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Create cross-platform Qt Help files

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/MapHotkeys.html b/web/help/MapHotkeys.html index bc9d69aa..85093bef 100644 --- a/web/help/MapHotkeys.html +++ b/web/help/MapHotkeys.html @@ -1,80 +1,271 @@ - - + + + + + - Map Hotkeys - - - - - - - - - - + + + + + + + + Map Hotkeys + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Map Hotkeys

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Map Hotkeys

-


-

The map hotkeys dialog allows you to assign hotkeys to various FCEUX commands.

-


-

To assign or remove a hotkey assignment, double click on the name of the hotkey in the list box.  Then press the key combination you wish to assign it.  To clear the assignment, press the clear button.

-


-

The filter pull down menu allows you to only see hotkey listings in various categories (the list shows all hotkey assignments by default).

-


-

The Restore defaults button will change all hotkeys to their default values.

-

-

Created with the Personal Edition of HelpNDoc: Full-featured Help generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Map Hotkeys

+ +
+ +

+

Map Hotkeys

+


+

The map hotkeys dialog allows you to assign hotkeys to various FCEUX commands.

+


+

To assign or remove a hotkey assignment, double click on the name of the hotkey in the list box.  Then press the key combination you wish to assign it.  To clear the assignment, press the clear button.

+


+

The filter pull down menu allows you to only see hotkey listings in various categories (the list shows all hotkey assignments by default).

+


+

The Restore defaults button will change all hotkeys to their default values.

+

+

Created with the Personal Edition of HelpNDoc: Easily create Help documents

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/MemoryWatch.html b/web/help/MemoryWatch.html index 66da923a..a238d6ed 100644 --- a/web/help/MemoryWatch.html +++ b/web/help/MemoryWatch.html @@ -1,133 +1,324 @@ - - + + + + + - Memory Watch - - - - - - - - - - + + + + + + + + Memory Watch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Memory Watch

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Memory Watch

-


-

Overview

-


-

Memory watch is a tool designed to values of specific known memory values in the game's RAM. Memory watch does not find values.  To find useful values to monitor, see Cheats, Ram filter, Hex Editor, and Debugger.

-


-


-

Inserting Values

-


-

To display a ram value, simply type its address into one of the address fields.  The name field allows you to put a brief description of the value.  

-


-


-

Prefixes

-


-

You must put in the hexi-decimal value of the address,  but the value will be displayed will be decimal by default.

-


-

To display the value in hex, use a prefix of "x" (such as x00FD).  

-


-

Use the prefix "!" to display a 2 byte value.

-


-

Use a prefix of "X" to watch a 2 byte value in hex.

-


-


-

Saving/Loading Watch files

-


-

You can save your addresses into watch files, as well as loading previous files using the standard save,load,new options in the File menu.

-


-

FCEUX uses the /memw folder by default but you can specify a new default folder in the Directory Override menu.

-


-


-

Options Menu

-


-

If you select Load on Start up, Memory watch will load up automatically when FCEU is started.

-


-

If you select Load Last File on Start up, the most recent file in the Recent folder will be loaded when memory watch is loaded.

-


-

If you select Collapse to 1 Column (or press the right arrow button on the bottom left of the dialog), the memory watch dialog is reduced to just 1 column.

-


-

Frozen Memory Addresses

-


-

If one of the watched addresses is frozen by the cheats dialog or the hex editor, it will display blue in the memory watch dialog.

-


-


-

Memory Change Monitor

-


-

The bottom of the memory watch dialog displays a memory change monitoring section.  This monitors the 1st two values of each memory watch column.  Rather than monitoring the value itself, this monitors the value's behavior.  

-


-

The address being monitored is under the address column.

-


-

The Formula drop down box shows which criteria the change monitoring is using.

-


-

The count value displays how many times the value has changed based on the criteria.

-


-

Reset will reset the count to 0.

-


-


-

Usage Example:

-


-

As an example of the memory change monitoring, Let's say we are recording a movie of the game Super C and want to keep track of when the game lags.

-

The ram address 001C functions as a "lag flag".  It will remain 0, then change to a positive value on a frame that the game lags.

-


-

We could put 001C in one of the 1st two memory watch edit boxes.  Then set the corresponding formula in the memory change monitoring to "> then" (greater than).  Now the count will show us how many lag frames occur in the movie.

-

-

Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Memory Watch

+ +
+ +

+

Memory Watch

+


+

Overview

+


+

Memory watch is a tool designed to values of specific known memory values in the game's RAM. Memory watch does not find values.  To find useful values to monitor, see Cheats, Ram filter, Hex Editor, and Debugger.

+


+


+

Inserting Values

+


+

To display a ram value, simply type its address into one of the address fields.  The name field allows you to put a brief description of the value.   

+


+


+

Prefixes

+


+

You must put in the hexi-decimal value of the address,  but the value will be displayed will be decimal by default.

+


+

To display the value in hex, use a prefix of "x" (such as x00FD).  

+


+

Use the prefix "!" to display a 2 byte value. 

+


+

Use a prefix of "X" to watch a 2 byte value in hex.

+


+


+

Saving/Loading Watch files

+


+

You can save your addresses into watch files, as well as loading previous files using the standard save,load,new options in the File menu.

+


+

FCEUX uses the /memw folder by default but you can specify a new default folder in the Directory Override menu.

+


+


+

Options Menu

+


+

If you select Load on Start up, Memory watch will load up automatically when FCEU is started. 

+


+

If you select Load Last File on Start up, the most recent file in the Recent folder will be loaded when memory watch is loaded.

+


+

If you select Collapse to 1 Column (or press the right arrow button on the bottom left of the dialog), the memory watch dialog is reduced to just 1 column.

+


+

Frozen Memory Addresses

+


+

If one of the watched addresses is frozen by the cheats dialog or the hex editor, it will display blue in the memory watch dialog.

+


+


+

Memory Change Monitor

+


+

The bottom of the memory watch dialog displays a memory change monitoring section.  This monitors the 1st two values of each memory watch column.  Rather than monitoring the value itself, this monitors the value's behavior.  

+


+

The address being monitored is under the address column.

+


+

The Formula drop down box shows which criteria the change monitoring is using.

+


+

The count value displays how many times the value has changed based on the criteria.

+


+

Reset will reset the count to 0.

+


+


+

Usage Example:

+


+

As an example of the memory change monitoring, Let's say we are recording a movie of the game Super C and want to keep track of when the game lags.

+

The ram address 001C functions as a "lag flag".  It will remain 0, then change to a positive value on a frame that the game lags.

+


+

We could put 001C in one of the 1st two memory watch edit boxes.  Then set the corresponding formula in the memory change monitoring to "> then" (greater than).  Now the count will show us how many lag frames occur in the movie.

+

+

Created with the Personal Edition of HelpNDoc: Easy CHM and documentation editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/MovieOptions.html b/web/help/MovieOptions.html index 24abd014..23853cda 100644 --- a/web/help/MovieOptions.html +++ b/web/help/MovieOptions.html @@ -1,118 +1,309 @@ - - + + + + + - Movie Options - - - - - - - - - - + + + + + + + + Movie Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Movie Options

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Movie Options

-


-


-

The movie option dialog has various settings related to movie making.

-


-

Always suggest Read-Only replay

-


-

If checked, FCEUX will automatically check "Open Read-Only" checkbox when showing "Play Movie" dialog. If unchecked, the "Open Read-Only" checkbox state will depend on current movie status.

-


-


-

Pause After Movie Playback

-


-

If checked, FCEUX will automatically pause emulation when reaching the last frame of a movie file.

-


-


-

Close After Movie Playback

-


-

If checked, FCEUX will close the movie after replaying its last frame. If unchecked, when reaching the last frame the movie will switch to "MOVIE_FINISHED" state, still allowing you to load its savestates.

-


-


-

Bind savestates to movies

-


-

Affects the savestate naming system when a movie is loaded.  If checked, the movie name will be appended to a savestate filename.

-


-


-

Display movie subtitles

-


-

Toggles whether or not movie subtitles (imbedded into the .fm2 file, see .fm2 documentation) will be displayed on screen.

-


-


-

Put movie subtitles in AVI

-


-

Toggles whether or not movie subtitles will be recorded into a .avi file.

-


-


-

Automatically backup movies

-


-

If checked, the auto-movie backup is toggled on.  Whenever a movie is loaded then set into record mode (by loading a savestate while in read-write mode), a backup copy of the .fm2 is saved before changing the file.  

-


-

Movie backups will be created only once each time a movie is loaded into FCEUX.  Movie backups are appended with a backup number and the .bak file extension.

-


-


-

Load full savestate-movies

-


-

If checked, FCEUX will not truncate movie immediately when you load its savestate in Recording mode (thus behaving similar to VBA-rr and Snes9x emulators). If unchecked, the movie will always shrink to the frame of the savestate you loaded.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Movie Options

+ +
+ +

+

Movie Options

+


+


+

The movie option dialog has various settings related to movie making.

+


+

Always suggest Read-Only replay

+


+

If checked, FCEUX will automatically check "Open Read-Only" checkbox when showing "Play Movie" dialog. If unchecked, the "Open Read-Only" checkbox state will depend on current movie status.

+


+


+

Pause After Movie Playback

+


+

If checked, FCEUX will automatically pause emulation when reaching the last frame of a movie file.

+


+


+

Close After Movie Playback

+


+

If checked, FCEUX will close the movie after replaying its last frame. If unchecked, when reaching the last frame the movie will switch to "MOVIE_FINISHED" state, still allowing you to load its savestates.

+


+


+

Bind savestates to movies

+


+

Affects the savestate naming system when a movie is loaded.  If checked, the movie name will be appended to a savestate filename.

+


+


+

Display movie subtitles

+


+

Toggles whether or not movie subtitles (imbedded into the .fm2 file, see .fm2 documentation) will be displayed on screen.

+


+


+

Put movie subtitles in AVI

+


+

Toggles whether or not movie subtitles will be recorded into a .avi file.

+


+


+

Automatically backup movies

+


+

If checked, the auto-movie backup is toggled on.  Whenever a movie is loaded then set into record mode (by loading a savestate while in read-write mode), a backup copy of the .fm2 is saved before changing the file.  

+


+

Movie backups will be created only once each time a movie is loaded into FCEUX.  Movie backups are appended with a backup number and the .bak file extension.

+


+


+

Load full savestate-movies

+


+

If checked, FCEUX will not truncate movie immediately when you load its savestate in Recording mode (thus behaving similar to VBA-rr and Snes9x emulators). If unchecked, the movie will always shrink to the frame of the savestate you loaded.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Free EPub producer

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/MovieRecording.html b/web/help/MovieRecording.html index f8ab1ab0..24ad69fb 100644 --- a/web/help/MovieRecording.html +++ b/web/help/MovieRecording.html @@ -1,157 +1,348 @@ - - + + + + + - Movie Recording - - - - - - - - - - + + + + + + + + Movie Recording + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Movie Recording

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Movie Recording

-


-

Introduction

-


-

A movie file is a file which contains data needed to reconstruct actions in a game. In most emulators, the movie files consist of simply the buttons that were pressed during the game. Because the emulation is completely predictable (deterministic), it will always play back the same way.

-


-

Unless the movie starts from the console power-on or from reset, the movie file might also contain a savestate that loads the beginning point of the game.  Movie files don’t contain any sound or image data. Such data is not needed, because the emulator can reconstruct it during movie playback.

-


-

Movie files in FCEUX are .fm2 files.  The file format is unique to FCEUX and not compatible with other movie recording versions of FCE Ultra.  Movie files from other versions (.fcm) can be converted to .fm2 for playback with the .fcm to .fm2 converter.

-


-

Movie features in FCEUX are designed specifically for making Tool-assisted Speedruns.  For more information visit TASVideos.

-


-

Recording Movies

-


-

To record a movie, open a ROM.  Then simply select "Record Movie" in the File > Movie Menu.  You will be prompted to name the file and to select where to record from.  Selecting "Start" will begin the recording from a Power-on (Hard Reset).  If you select "Now", a savestate will be made at your current location in the game, and the movie will begin recording from there.  If you select browse, you will be prompted to find a preexisting savestate file to begin recording from.

-


-


-

Savestates, Slowdown, and Frame Advance

-


-

At anytime while recording, you can make a *savestate.  This is a snapshot of the game's current memory contents.  Once a savestate is made, it can be loaded with the *loadstate command.  This will return the movie back to the spot in the game where the savestate was made.  This can be used to undo mistakes or to test different strategies for a particular segment.

-


-

(The default key for making a savestate is "I" and the default key for loading a state is "P".  Both of these can be assigned under the Map Hotkeys Menu).  Both can also be access through the File > Savestate Menu

-


-

Tool Assisted movies take advantage of slowing the emulator down in order to increase precision of the movie making process.  Navigating to NES > Emulation Speed > Slow down or pressing the "-" key will slow down emulation.  NES > Emulation Speed > Speed up or the "=" will speed it up.  (These can be re-mapped in the Map Hotkeys Menu).

-


-

Even greater precision can be made using the frame advance key.  Pressing the frame advance key will pause emulation and advance it a single frame (1/60th of a second NTSC ).  By holding down input and pressing the frame advance key, it will record that input for that particular frame.

-


-

For more info seeing Tool Assisted Speedruns.

-


-


-

"Bullet Proof Rerecording"

-


-

All savestates made during movie recording contain the movie information up to the frame of the savestate.  When a savestate is loaded, the movie file in the savestate is also loaded.  This is referred to as "Bullet Proof Rerecording" because it prevents possible desyncs and lost data from improper/out of order savestate loading.

-


-


-

Playing Back Movies

-


-

To play back a recorded movie, open the ROM.  Then select "Replay Movie" in the File Menu.  A movie dialog box will open where you can select the movie file.  

-


-

You can also select whether the movie is in Read-only mode.  If a movie is in read-only mode, the movie file can not be altered in any way.  If you make a savestate while playing the movie and load that state, the playback will simply "rewind" to that state.  If the movie is not in read-only, however, loading a state will set the movie to record mode and begin recording from that savestate.

-


-

You can also select "Pause movie at frame" x.  If selected, the movie will automatically pause when reaching the frame selected (the default is the last frame of the movie).

-


-


-

Read only

-


-

You can select read-only when playing a movie.  You can also toggle the read-only status by navigating to File > Movie > Read only.

-

In read-only mode a movie can not be edited.  Loading a savestate will take the movie to that point in the movie and stay in playback mode.

-


-

In read-write status, loading a state will change a movie from playback mode to record mode.

-


-


-

Resuming Recording

-


-

You can resume recording a previous movie by playing back the movie, setting the record status to read+write, and then loading a state.

-


-


-

Play Movie from Beginning

-


-

At any point while recording or playing back a movie, you can navigate to File > Movie > Play Movie from Beginning.  This will set the movie to read only status and reset playback to frame 0.

-


-

Frame Counter

-


-

The Frame counter displays what frame the movie is currently on.  If the movie is playing in read-only mode, it will also display the total number of frames in the movie.  The default key for toggling the Frame Counter display is the "." (period) key.  (This can be re-mapped in the Map Hotkeys Menu).

-


-


-

Frame Advance

-


-

The frame advance key ("backlash" key by default.  Re-mappable under the Map Hotkeys Menu) will advance the game by a single frame and then pause the game.   If the hotkey is held down, it will auto advance quickly through the game.

-


-

This is a critical tool when perfecting input in movie recording.

-


-

Metadata

-


-

When you record a new movie via the record movie dialog there is an author field.  This sends the info to the .fm2 file in the form of comment Author [author name] (see .fm2).  

-


-

Any line in the .fm2 that starts with "comment" is known as metadata.  You can include any number of comments manually by editing the .fm2 file with any text editor.  

-


-

On the replay movie dialog, clicking the metadata button will display all metadata in a separate dialog box (If a movie is currently loaded you can also access the meta-data by right-clicking and selecting Metadata in the context menu).

-


-


-

Subtitles

-


-

FCEUX now supports subtitles in the .fm2 file format.  Subtitles will be displayed on the screen automatically as a movie plays.  You can turn on/off subtitles by navigating to Config > Movie Options > Display movie subtitles (see Movie options).

-


-

For adding subtitles to a movie see the .fm2 documentation.

-

-

Created with the Personal Edition of HelpNDoc: Easily create Web Help sites

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Movie Recording

+ +
+ +

+

Movie Recording

+


+

Introduction

+


+

A movie file is a file which contains data needed to reconstruct actions in a game. In most emulators, the movie files consist of simply the buttons that were pressed during the game. Because the emulation is completely predictable (deterministic), it will always play back the same way.

+


+

Unless the movie starts from the console power-on or from reset, the movie file might also contain a savestate that loads the beginning point of the game.  Movie files don’t contain any sound or image data. Such data is not needed, because the emulator can reconstruct it during movie playback. 

+


+

Movie files in FCEUX are .fm2 files.  The file format is unique to FCEUX and not compatible with other movie recording versions of FCE Ultra.  Movie files from other versions (.fcm) can be converted to .fm2 for playback with the .fcm to .fm2 converter.

+


+

Movie features in FCEUX are designed specifically for making Tool-assisted Speedruns.  For more information visit TASVideos.

+


+

Recording Movies

+


+

To record a movie, open a ROM.  Then simply select "Record Movie" in the File > Movie Menu.  You will be prompted to name the file and to select where to record from.  Selecting "Start" will begin the recording from a Power-on (Hard Reset).  If you select "Now", a savestate will be made at your current location in the game, and the movie will begin recording from there.  If you select browse, you will be prompted to find a preexisting savestate file to begin recording from.

+


+


+

Savestates, Slowdown, and Frame Advance

+


+

At anytime while recording, you can make a *savestate.  This is a snapshot of the game's current memory contents.  Once a savestate is made, it can be loaded with the *loadstate command.  This will return the movie back to the spot in the game where the savestate was made.  This can be used to undo mistakes or to test different strategies for a particular segment.

+


+

(The default key for making a savestate is "I" and the default key for loading a state is "P".  Both of these can be assigned under the Map Hotkeys Menu).  Both can also be access through the File > Savestate Menu

+


+

Tool Assisted movies take advantage of slowing the emulator down in order to increase precision of the movie making process.  Navigating to NES > Emulation Speed > Slow down or pressing the "-" key will slow down emulation.  NES > Emulation Speed > Speed up or the "=" will speed it up.  (These can be re-mapped in the Map Hotkeys Menu).

+


+

Even greater precision can be made using the frame advance key.  Pressing the frame advance key will pause emulation and advance it a single frame (1/60th of a second NTSC ).  By holding down input and pressing the frame advance key, it will record that input for that particular frame.

+


+

For more info seeing Tool Assisted Speedruns.

+


+


+

"Bullet Proof Rerecording"

+


+

All savestates made during movie recording contain the movie information up to the frame of the savestate.  When a savestate is loaded, the movie file in the savestate is also loaded.  This is referred to as "Bullet Proof Rerecording" because it prevents possible desyncs and lost data from improper/out of order savestate loading.

+


+


+

Playing Back Movies

+


+

To play back a recorded movie, open the ROM.  Then select "Replay Movie" in the File Menu.  A movie dialog box will open where you can select the movie file.  

+


+

You can also select whether the movie is in Read-only mode.  If a movie is in read-only mode, the movie file can not be altered in any way.  If you make a savestate while playing the movie and load that state, the playback will simply "rewind" to that state.  If the movie is not in read-only, however, loading a state will set the movie to record mode and begin recording from that savestate.

+


+

You can also select "Pause movie at frame" x.  If selected, the movie will automatically pause when reaching the frame selected (the default is the last frame of the movie).

+


+


+

Read only

+


+

You can select read-only when playing a movie.  You can also toggle the read-only status by navigating to File > Movie > Read only.

+

In read-only mode a movie can not be edited.  Loading a savestate will take the movie to that point in the movie and stay in playback mode.

+


+

In read-write status, loading a state will change a movie from playback mode to record mode.

+


+


+

Resuming Recording

+


+

You can resume recording a previous movie by playing back the movie, setting the record status to read+write, and then loading a state.

+


+


+

Play Movie from Beginning

+


+

At any point while recording or playing back a movie, you can navigate to File > Movie > Play Movie from Beginning.  This will set the movie to read only status and reset playback to frame 0.

+


+

Frame Counter

+


+

The Frame counter displays what frame the movie is currently on.  If the movie is playing in read-only mode, it will also display the total number of frames in the movie.  The default key for toggling the Frame Counter display is the "." (period) key.  (This can be re-mapped in the Map Hotkeys Menu).

+


+


+

Frame Advance

+


+

The frame advance key ("backlash" key by default.  Re-mappable under the Map Hotkeys Menu) will advance the game by a single frame and then pause the game.   If the hotkey is held down, it will auto advance quickly through the game.

+


+

This is a critical tool when perfecting input in movie recording.

+


+

Metadata

+


+

When you record a new movie via the record movie dialog there is an author field.  This sends the info to the .fm2 file in the form of comment Author [author name] (see .fm2).  

+


+

Any line in the .fm2 that starts with "comment" is known as metadata.  You can include any number of comments manually by editing the .fm2 file with any text editor.  

+


+

On the replay movie dialog, clicking the metadata button will display all metadata in a separate dialog box (If a movie is currently loaded you can also access the meta-data by right-clicking and selecting Metadata in the context menu).

+


+


+

Subtitles

+


+

FCEUX now supports subtitles in the .fm2 file format.  Subtitles will be displayed on the screen automatically as a movie plays.  You can turn on/off subtitles by navigating to Config > Movie Options > Display movie subtitles (see Movie options).

+


+

For adding subtitles to a movie see the .fm2 documentation.

+

+

Created with the Personal Edition of HelpNDoc: Produce online help for Qt applications

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Movieformats.html b/web/help/Movieformats.html index fe374758..283d3fec 100644 --- a/web/help/Movieformats.html +++ b/web/help/Movieformats.html @@ -1,80 +1,271 @@ - - + + + + + - Movie & Savestate formats - - - - - - - - - - + + + + + + + + Movie & Savestate formats + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Movie & Savestate formats

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Movie and Savestate File Formats

-


-

The Following documentation deals with the specific technical information regarding the format of movie & savestate files.

-


-

.fm2 - FCEUX Movie file format

-


-

.fcm - Movie file format from previous FCEU versions (compatible with FCEUX via Convert FCM)

-


-

.fcs - Savestate file format

-

-

Created with the Personal Edition of HelpNDoc: Easy CHM and documentation editor

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Movie & Savestate formats

+ +
+ +

+

Movie and Savestate File Formats

+


+

The Following documentation deals with the specific technical information regarding the format of movie & savestate files.

+


+

.fm2 - FCEUX Movie file format

+


+

.fcm - Movie file format from previous FCEU versions (compatible with FCEUX via Convert FCM)

+


+

.fcs - Savestate file format

+

+

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NES.html b/web/help/NES.html index c356078f..6660a35e 100644 --- a/web/help/NES.html +++ b/web/help/NES.html @@ -1,120 +1,311 @@ - - + + + + + - NES Menu - - - - - - - - - - + + + + + + + + NES Menu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NES Menu

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

NES

-


-

Explains commands in the NES menu of FCEUX.

-

All these commands can be mapped to a keyboard/joypad button in the Map Hotkeys Menu.

-


-

Reset

-

Emulates the pressing of the Reset Button on the NES. ("Soft reset").

-


-

Power

-

Emulates a power cycle, which is turning the power on and off with the Power button on the NES. ("Hard Reset")

-


-

Eject/Insert Disk

-

Ejects or inserts a FDS disk.  (See Famicom Disk System)

-


-

Switch Disk Side

-

Switches Sides of a FDS disk. (See Famicom Disk System)

-


-

Insert Coin

-

Emulates the inserting of a coin in an arcade-style game.

-


-


-

Emulation Speed Sub Menu

-


-

Speed Up

-

Speeds up emulation (emulation speed ranges from 1% to 6400%)

-


-

Slow Down

-

Slows down emulation

-


-

Slowest Speed

-

Sets emulation to 1% speed

-


-

Normal Speed

-

Sets emulation speed to 100%

-


-

Turbo

-

Toggles turbo mode.   In turbo mode, emulation is set its fastest settings.

-


-

Set Custom Speed

-

Allows you to define emulation speed by entering the number of percents (1-1000, default is 100%)

-


-

Set FrameAdvance Delay

-

Here you can fine-tune the working of the Frame Advance key. This setting defines the delay between the moment you press Frame Advance and the moment it starts continuous emulation

-


-

Set custom speed for FrameAdvance

-

Here you can fine-tune the working of the Frame Advance key. This setting defines the speed of continuous emulation while you're holding Frame Advance. If you leave it 0 (zero), the emulation speed will be the same as the current emulation speed (from 1% to 6400%), but if you enter a number from 1 to 1000, the current emulation speed will be ignored when holding Frame Advance.

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured Kindle eBooks generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NES Menu

+ +
+ +

+

NES

+


+

Explains commands in the NES menu of FCEUX.

+

All these commands can be mapped to a keyboard/joypad button in the Map Hotkeys Menu.

+


+

Reset

+

Emulates the pressing of the Reset Button on the NES. ("Soft reset").

+


+

Power

+

Emulates a power cycle, which is turning the power on and off with the Power button on the NES. ("Hard Reset")

+


+

Eject/Insert Disk

+

Ejects or inserts a FDS disk.  (See Famicom Disk System)

+


+

Switch Disk Side

+

Switches Sides of a FDS disk. (See Famicom Disk System)

+


+

Insert Coin

+

Emulates the inserting of a coin in an arcade-style game.

+


+


+

Emulation Speed Sub Menu

+


+

Speed Up

+

Speeds up emulation (emulation speed ranges from 1% to 6400%)

+


+

Slow Down

+

Slows down emulation

+


+

Slowest Speed

+

Sets emulation to 1% speed

+


+

Normal Speed

+

Sets emulation speed to 100%

+


+

Turbo

+

Toggles turbo mode.   In turbo mode, emulation is set its fastest settings.

+


+

Set Custom Speed

+

Allows you to define emulation speed by entering the number of percents (1-1000, default is 100%)

+


+

Set FrameAdvance Delay

+

Here you can fine-tune the working of the Frame Advance key. This setting defines the delay between the moment you press Frame Advance and the moment it starts continuous emulation

+


+

Set custom speed for FrameAdvance

+

Here you can fine-tune the working of the Frame Advance key. This setting defines the speed of continuous emulation while you're holding Frame Advance. If you leave it 0 (zero), the emulation speed will be the same as the current emulation speed (from 1% to 6400%), but if you enter a number from 1 to 1000, the current emulation speed will be ignored when holding Frame Advance.

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easy to use tool to create HTML Help files and Help web sites

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NESProcessor.html b/web/help/NESProcessor.html index 8cd32d5a..9eb7dd77 100644 --- a/web/help/NESProcessor.html +++ b/web/help/NESProcessor.html @@ -1,82 +1,273 @@ - - + + + + + - NES Processing - - - - - - - - - - + + + + + + + + NES Processing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NES Processing

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

NES Processing

-


-

Includes Technical Specifications for the emulation of the NES CPU (6502) and the NES PPU (2C02).

-


-

CPU

-


-

PPU

-


-

NES Scrolling part 1

-


-

NES Scrolling part 2

-

-

Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NES Processing

+ +
+ +

+

NES Processing

+


+

Includes Technical Specifications for the emulation of the NES CPU (6502) and the NES PPU (2C02).

+


+

CPU

+


+

PPU

+


+

NES Scrolling part 1

+


+

NES Scrolling part 2 

+

+

Created with the Personal Edition of HelpNDoc: News and information about help authoring tools and software

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NESRAMMappingFindingValues.html b/web/help/NESRAMMappingFindingValues.html index d8a02909..1d804ce4 100644 --- a/web/help/NESRAMMappingFindingValues.html +++ b/web/help/NESRAMMappingFindingValues.html @@ -1,279 +1,470 @@ - - + + + + + - NES RAM (Mapping/Finding Values) - - - - - - - - - - + + + + + + + + NES RAM (Mapping/Finding Values) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NES RAM (Mapping/Finding Values)

- -
- FAQ / Guides ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

NES Mapping

-


-

This guide gives a map of the addresses in the NES cpu and explains each portion in detail.  

-


-

It also provides information for the basic layout of ram values in typical NES games.  This info can be used to quickly map and find useful values in the game's ram.

-


-

Contents

-


-

Memory Map

-

       Gives a diagram of the 2A03 CPU memory map .

-


-

2C02 PPU memory map

-

       Gives more detailed info about each section of the Memory map diagram

-


-

Game Ram Details

-

       On board RAM Map ($000-$07FF) Map (gives specific info on the how NES games typically layout their ram values)

-


-

Online Resources

-

NES Programming - Wikipedia

-

NES Memory Map

-


-


-

Memory Map (NES RAM/ROM)

-


-

2A03 CPU memory map

-

2A03 CPU is a 6502-compatible CPU without the decimal mode (CLD and SED do nothing). It has an on-die sound generator, very limited DMA capability, and an input device controller that can be accessed through the 2A03 registers.

-


-

                                                                                                                                           

-

6502 CPU Memory Map                                                                                                                              

-

Address Range                Size in bytes        Notes (Page size = 256bytes)

-

(Hexadecimal)                                                                                                                                                                                    

-


-

$0000 - $07FF                2048                Game Ram

-


-

($0000 - $00FF)                256                Zero Page - Special Zero Page addressing modes give faster memory read/write access

-

($0100 - $01FF)                256                Stack memory

-

($0200 - $07FF)                1536                RAM

-

                                                                                                                                                                                                               

-


-

$0800 - $0FFF                2048                Mirror of $0000-$07FF        

-


-

($0800 - $08FF)                256                 Zero Page

-

($0900 - $09FF)        256                Stack

-

($0A00 - $0FFF)                1024                Ram

-

                                                                                                                                                                                                               

-


-

$1000 - $17FF                2048 bytes        Mirror of $0000-$07FF

-


-

($1000 - $10FF)                256                Zero Page

-

$1100 - $11FF                256                Stack

-

$1200 - $17FF                1024                RAM

-

                                                                                                                                                                                                               

-


-

$1800 - $1FFF                2048 bytes        Mirror of $0000-$07FF        

-


-

($1800 - $18FF)                256                Zero Page

-

($1900 - $19FF)                256                Stack

-

($1A00 - $1FFF)        1024                RAM

-

                                                                                                                                                                                                               

-


-

$2000 - $2007                8 bytes                Input / Output registers

-

$2008 - $3FFF                8184 bytes        Mirror of $2000-$2007 (mulitple times)

-

                                                                                                                                                                                                               

-


-

$4000 - $401F                32 bytes        Input / Output registers

-

$4020 - $5FFF                8160 bytes        Expansion ROM - Used with Nintendo's MMC5 to expand the capabilities of VRAM.

-

                                                                                                                                                                                                               

-


-

$6000 - $7FFF                8192 bytes        SRAM - Save Ram used to save data between game plays.

-

                                                                                                                                                                                                               

-


-

$8000 - $BFFF                16384 bytes        PRG-ROM lower bank - executable code

-

$C000 - $FFFF                16384 bytes        PRG-ROM upper bank - executable code

-

$FFFA - $FFFB        2 bytes                Address of Non Maskable Interrupt (NMI) handler routine

-

$FFFC - $FFFD        2 bytes                Address of Power on reset handler routine

-

$FFFE - $FFFF                2 bytes                Address of Break (BRK instruction) handler routine

-

                                                                                                                                                                                                               

-


-


-

2C02 PPU memory map

-


-

2C02 PPU is a character generator with sprites, designed by Nintendo specifically for the NES.

-


-

    __________________________________________

-

0000| Pattern table 0                          |

-

   |__________________________________________|

-

1000| Pattern table 1                          |

-

   |__________________________________________|   _____ _____

-

2000| Nametable 0                              |  |     |     |

-

   |__________________________________________|  |  0  |  1  |

-

2400| Nametable 1                              |  |_____|_____|

-

   |__________________________________________|  |     |     |

-

2800| Nametable 2                              |  |  2  |  3  |

-

   |__________________________________________|  |_____|_____|

-

2c00| Nametable 3                              |

-

   |__________________________________________|

-

3000| Mirror of $2000-$2eff                    |

-

   |__________________________________________|

-

3f00| Palette                                  |

-

   |__________________________________________|

-

3f20| Mirrors of $3f00-$3f1f                   |

-

   |__________________________________________|

-


-

The NES PPU has enough RAM for two nametables (0 and 3); it brings some PPU nametable address lines to the cart edge so that the cart can decide whether to map 0 onto 2 and 1 onto 3 (vertical mirroring as in Super Mario Brothers and Contra) or 0 onto 1 and 2 onto 3 (horizontal mirroring as in Kid Icarus and Ikari), all screens to either 0 or 3 (as in many Rare games such as Battletoads and Jeopardy!), or all screens to RAM on the cartridge (as in Gauntlet). Split-screen games that scroll in all four directions (such as Super Mario Brothers 3 and Kirby's Adventure) often use vertical or one-screen mirroring (with a small amount of screen corruption at the sides due to tiles wrapping around the sides) and stick the status bar in some random unused area of the screen.

-


-


-

Game RAM Details

-

       Mapping RAM/Finding Ram

-

       Written by: adelikat

-


-

This guide is written specifically for finding useful values for TAS movie making.  

-

It does not tell you how to use specific tools to find values.  For that refer to Hex editor, Cheat Search, and RAM filter.

-


-

Most games use the basic on board ram.  The address range of this ram is $0000-$07FF.  This translates to 2048 possible ram values.

-


-

Pages

-


-

This ram is broken down into 8 pages.  A "page" is a block of 256 ram values.

-


-

I will refer to these values as such:

-

Block 0                $00xx                ($0000-$00FF)

-

Block 1                $01xx                ($0100-$01FF)

-

Block 2                $02xx                ($0200-$02FF)

-

Block 3                $03xx                ($0300-$03FF)

-

Block 4                $04xx                ($0400-$04FF)

-

Block 5                $05xx                ($0500-$05FF)

-

Block 6                $06xx                ($0600-$06FF)

-

Block 7                $07xx                ($0700-$07FF)

-


-

Each block will be organized will similar data.  For instance, all sprite data will be in the same block.  Enemy/Player statistics (energy, coordinates, speed, etc.) will be in another.  For instance, if you find the main character's HP and it is located in block 3, you know that the remaining stats for the character are also in that block.  This can significantly cut down time when trying to find related values.

-


-

There are always the following blocks:

-


-

Sprite Data                Block 2

-


-

I've yet to see map a game that does not use this block solely for sprite data.  It will contain the "ID" numbers for all the items currently on the screen.  Simply put, this data is precisely the data you see on the screen.  For making TAS movies this is not useful data.  If you are using cheat search and have narrowed it down your search to a few values, you can immediately discard any $02xx values.

-


-

In games with a lot of sprite data, I've seen blocks 1 & 3 also reserved for sprite data.

-


-

Music & Sound FX        Block 1 or 7, generally

-


-

This one has more deviation, but almost all games reserve an entire block for memory allocated to the game's Music and Sound FX.  Again, for TAS purposes these values are not *useful. By finding even 1 of these values, you can eliminate that block from your search possibilities.   Finding which block is reserved for music is often quite simple with the Hex editor.  Watching the ram values with the game playing, you can see which addresses "move to the beat".  

-


-

*Actually they can come in handy for "dancing to the beat"

-


-

Player & Enemy Stats        Blocks 1,3,4,5 generally (any or all of these)

-


-

This is your "sweet spot" for movie making, as often you will be wanting to track the players speed or coordinates, enemy energy, or enemy coordinates.

-


-

These values rarely (if at all) reside outside blocks 1, 3, 4, or 5.  This knowledge already reduces your search possibilities in half!

-


-

Rows

-


-

Each block is broken down into 16 "rows" of addresses.  For example, in block 3, the first row is $030x ($0300-$030F).

-


-

Each row of 16* will contain similar data.  For instance all x coordinates will generally be in the same row.  So xxx0 might be the main characters x position.  xxxx1 would be "enemy 1" (1st enemy loaded onto the screen), and so on.

-


-

The y coordinates would be in another row, x subpixel values in yet another row, etc.

-


-

*Super Mario Bros. 2 (U) is a rare example that uses rows of 10

-


-

Columns

-


-

A column would be all the values of a block that share the same last digit.  So a column would be 16 addresses such as $0300, $0310, $0320, etc.

-


-

For enemy/player stats, columns usually refer to the same player or enemy.

-


-

So for example, if a player's energy was stored in $0300.  The remaining row will be other player/enemy's energy.  

-


-

If the next row ($031x) is x positions.  $0310 would be the player's x position.  The remaining positions of that row would correspond to the other player/enemy x positions in line with the hp values of the previous row.

-


-

Example

-


-

These distinctions are easier to see in a visual example.  This is the enemy/player stats as they are mapped in the game Teenage Mutant Ninja Turtles.

-


-

Block 4

-

                           P  W1 W2 W3 E1 E2 E3 E4 E5 E6 E7 E8 X  X  X  X  

-

Sprite ID:        040x: 09 00 00 00 00 9E 9E 9E 9E 00 00 00 00 00 00 00

-

ID counter:       041x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

Timer/sp change:  042x: 02 00 00 00 00 03 03 03 03 00 00 00 00 00 00 00

-

hit animation:    043x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

characteristics:  044x: 00 00 00 00 00 8D 8D 8D 8D 00 00 00 00 00 00 00

-

characteristics:  045x: C2 00 00 00 00 C2 C2 C3 C3 00 00 00 00 00 00 00

-

Y position:       046x: 4C 00 00 00 00 B4 B4 64 B4 00 00 00 00 00 00 00

-

Y subpixel:       047x: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

X position:       048x: 50 00 00 00 00 79 B9 CC CC 00 00 00 00 00 00 00

-

X subpixel:       049x: 80 00 00 00 00 C0 C0 C0 00 00 00 00 00 00 00 00

-

Not used:         04ax: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

Y pix speed:      04bx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

Y subpix speed:   04cx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

Not used:         04dx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

-

X pix speed:      04ex: 00 00 00 00 00 01 01 FE FE 00 00 00 00 00 00 00

-

X subpix speed:   04fx: 00 00 00 00 00 60 60 A0 A0 00 00 00 00 00 00 00

-


-

P = current turtle (player)

-

W = weapon (up to 3 on the screen at one time)

-

E = enemy (up to 8 on the screen at one time)

-

X = no use

-


-

E1 = "Enemy slot 1" which will be the first enemy on the screen loaded into memory.  The 2nd will be placed in "Enemy slot 2".  When enemy 1 is removed from memory (killed or goes off screen), the next enemy will be loaded into that slot.  Enemy's always take the lowest available slot when loaded.  Note: usually enemy slots are in reverse order.  So the first addresses is usually the last enemy slot loaded into memory.  TMNT is an exception.

-


-

All object (player, weapon, enemy) characteristics reside in block 4.

-

Each row is a different characteristic of each object on the screen (040x refers to a sprite ID of an object)

-

Each column corresponds to a specific object on the screen.  (All 04x0 's refer to the player).

-


-

See also, Memory Watch, Hex Editor, Cheat Search, Ram Filter, Movie Making, Tool Assisted Speedruns

-


-


-

-

Created with the Personal Edition of HelpNDoc: Free CHM Help documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NES RAM (Mapping/Finding Values)

+ +
+ +

+

NES Mapping

+


+

This guide gives a map of the addresses in the NES cpu and explains each portion in detail.  

+


+

It also provides information for the basic layout of ram values in typical NES games.  This info can be used to quickly map and find useful values in the game's ram.

+


+

Contents

+


+

Memory Map

+

       Gives a diagram of the 2A03 CPU memory map .

+


+

2C02 PPU memory map

+

       Gives more detailed info about each section of the Memory map diagram

+


+

Game Ram Details

+

       On board RAM Map ($000-$07FF) Map (gives specific info on the how NES games typically layout their ram values)

+


+

Online Resources

+

NES Programming - Wikipedia

+

NES Memory Map

+


+


+

Memory Map (NES RAM/ROM)

+


+

2A03 CPU memory map

+

2A03 CPU is a 6502-compatible CPU without the decimal mode (CLD and SED do nothing). It has an on-die sound generator, very limited DMA capability, and an input device controller that can be accessed through the 2A03 registers.

+


+

                                                                                                                                            

+

6502 CPU Memory Map                                                                                                                              

+

Address Range                 Size in bytes        Notes (Page size = 256bytes)

+

(Hexadecimal)                                                                                                                                                                                    

+


+

$0000 - $07FF                2048                Game Ram

+


+

($0000 - $00FF)                256                 Zero Page - Special Zero Page addressing modes give faster memory read/write access

+

($0100 - $01FF)                256                 Stack memory

+

($0200 - $07FF)                1536                 RAM

+

                                                                                                                                                                                                                

+


+

$0800 - $0FFF                 2048                  Mirror of $0000-$07FF         

+


+

($0800 - $08FF)                256                  Zero Page

+

($0900 - $09FF)         256                 Stack

+

($0A00 - $0FFF)                1024                Ram

+

                                                                                                                                                                                                                

+


+

$1000 - $17FF                 2048 bytes        Mirror of $0000-$07FF

+


+

($1000 - $10FF)                256                Zero Page

+

$1100 - $11FF                256                 Stack

+

$1200 - $17FF                 1024                RAM

+

                                                                                                                                                                                                                

+


+

$1800 - $1FFF                 2048 bytes         Mirror of $0000-$07FF         

+


+

($1800 - $18FF)                256                Zero Page

+

($1900 - $19FF)                256                Stack

+

($1A00 - $1FFF)         1024                RAM

+

                                                                                                                                                                                                                

+


+

$2000 - $2007                 8 bytes                 Input / Output registers

+

$2008 - $3FFF                 8184 bytes         Mirror of $2000-$2007 (mulitple times)

+

                                                                                                                                                                                                                

+


+

$4000 - $401F                 32 bytes         Input / Output registers

+

$4020 - $5FFF                 8160 bytes         Expansion ROM - Used with Nintendo's MMC5 to expand the capabilities of VRAM.

+

                                                                                                                                                                                                                

+


+

$6000 - $7FFF                 8192 bytes         SRAM - Save Ram used to save data between game plays.

+

                                                                                                                                                                                                                

+


+

$8000 - $BFFF                 16384 bytes         PRG-ROM lower bank - executable code

+

$C000 - $FFFF                 16384 bytes         PRG-ROM upper bank - executable code

+

$FFFA - $FFFB         2 bytes                 Address of Non Maskable Interrupt (NMI) handler routine

+

$FFFC - $FFFD         2 bytes                 Address of Power on reset handler routine

+

$FFFE - $FFFF                 2 bytes                 Address of Break (BRK instruction) handler routine

+

                                                                                                                                                                                                                

+


+


+

2C02 PPU memory map

+


+

2C02 PPU is a character generator with sprites, designed by Nintendo specifically for the NES.

+


+

     __________________________________________

+

0000| Pattern table 0                          |

+

    |__________________________________________|

+

1000| Pattern table 1                          |

+

    |__________________________________________|   _____ _____

+

2000| Nametable 0                              |  |     |     |

+

    |__________________________________________|  |  0  |  1  |

+

2400| Nametable 1                              |  |_____|_____|

+

    |__________________________________________|  |     |     |

+

2800| Nametable 2                              |  |  2  |  3  |

+

    |__________________________________________|  |_____|_____|

+

2c00| Nametable 3                              |

+

    |__________________________________________|

+

3000| Mirror of $2000-$2eff                    |

+

    |__________________________________________|

+

3f00| Palette                                  |

+

    |__________________________________________|

+

3f20| Mirrors of $3f00-$3f1f                   |

+

    |__________________________________________|

+


+

The NES PPU has enough RAM for two nametables (0 and 3); it brings some PPU nametable address lines to the cart edge so that the cart can decide whether to map 0 onto 2 and 1 onto 3 (vertical mirroring as in Super Mario Brothers and Contra) or 0 onto 1 and 2 onto 3 (horizontal mirroring as in Kid Icarus and Ikari), all screens to either 0 or 3 (as in many Rare games such as Battletoads and Jeopardy!), or all screens to RAM on the cartridge (as in Gauntlet). Split-screen games that scroll in all four directions (such as Super Mario Brothers 3 and Kirby's Adventure) often use vertical or one-screen mirroring (with a small amount of screen corruption at the sides due to tiles wrapping around the sides) and stick the status bar in some random unused area of the screen. 

+


+


+

Game RAM Details

+

       Mapping RAM/Finding Ram

+

       Written by: adelikat

+


+

This guide is written specifically for finding useful values for TAS movie making.  

+

It does not tell you how to use specific tools to find values.  For that refer to Hex editor, Cheat Search, and RAM filter.

+


+

Most games use the basic on board ram.  The address range of this ram is $0000-$07FF.  This translates to 2048 possible ram values.

+


+

Pages

+


+

This ram is broken down into 8 pages.  A "page" is a block of 256 ram values.

+


+

I will refer to these values as such:

+

Block 0                $00xx                ($0000-$00FF)

+

Block 1                $01xx                ($0100-$01FF)

+

Block 2                $02xx                ($0200-$02FF)

+

Block 3                $03xx                ($0300-$03FF)

+

Block 4                $04xx                ($0400-$04FF)

+

Block 5                $05xx                ($0500-$05FF)

+

Block 6                $06xx                ($0600-$06FF)

+

Block 7                $07xx                ($0700-$07FF)

+


+

Each block will be organized will similar data.  For instance, all sprite data will be in the same block.  Enemy/Player statistics (energy, coordinates, speed, etc.) will be in another.  For instance, if you find the main character's HP and it is located in block 3, you know that the remaining stats for the character are also in that block.  This can significantly cut down time when trying to find related values.

+


+

There are always the following blocks:

+


+

Sprite Data                Block 2

+


+

I've yet to see map a game that does not use this block solely for sprite data.  It will contain the "ID" numbers for all the items currently on the screen.  Simply put, this data is precisely the data you see on the screen.  For making TAS movies this is not useful data.  If you are using cheat search and have narrowed it down your search to a few values, you can immediately discard any $02xx values.

+


+

In games with a lot of sprite data, I've seen blocks 1 & 3 also reserved for sprite data.

+


+

Music & Sound FX        Block 1 or 7, generally

+


+

This one has more deviation, but almost all games reserve an entire block for memory allocated to the game's Music and Sound FX.  Again, for TAS purposes these values are not *useful. By finding even 1 of these values, you can eliminate that block from your search possibilities.   Finding which block is reserved for music is often quite simple with the Hex editor.  Watching the ram values with the game playing, you can see which addresses "move to the beat".  

+


+

*Actually they can come in handy for "dancing to the beat"

+


+

Player & Enemy Stats        Blocks 1,3,4,5 generally (any or all of these)

+


+

This is your "sweet spot" for movie making, as often you will be wanting to track the players speed or coordinates, enemy energy, or enemy coordinates.

+


+

These values rarely (if at all) reside outside blocks 1, 3, 4, or 5.  This knowledge already reduces your search possibilities in half!

+


+

Rows 

+


+

Each block is broken down into 16 "rows" of addresses.  For example, in block 3, the first row is $030x ($0300-$030F).

+


+

Each row of 16* will contain similar data.  For instance all x coordinates will generally be in the same row.  So xxx0 might be the main characters x position.  xxxx1 would be "enemy 1" (1st enemy loaded onto the screen), and so on.

+


+

The y coordinates would be in another row, x subpixel values in yet another row, etc.

+


+

*Super Mario Bros. 2 (U) is a rare example that uses rows of 10

+


+

Columns

+


+

A column would be all the values of a block that share the same last digit.  So a column would be 16 addresses such as $0300, $0310, $0320, etc.

+


+

For enemy/player stats, columns usually refer to the same player or enemy.

+


+

So for example, if a player's energy was stored in $0300.  The remaining row will be other player/enemy's energy.  

+


+

If the next row ($031x) is x positions.  $0310 would be the player's x position.  The remaining positions of that row would correspond to the other player/enemy x positions in line with the hp values of the previous row.

+


+

Example

+


+

These distinctions are easier to see in a visual example.  This is the enemy/player stats as they are mapped in the game Teenage Mutant Ninja Turtles.

+


+

Block 4

+

                           P  W1 W2 W3 E1 E2 E3 E4 E5 E6 E7 E8 X  X  X  X  

+

Sprite ID:        040x: 09 00 00 00 00 9E 9E 9E 9E 00 00 00 00 00 00 00

+

ID counter:       041x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

Timer/sp change:  042x: 02 00 00 00 00 03 03 03 03 00 00 00 00 00 00 00

+

hit animation:    043x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

characteristics:  044x: 00 00 00 00 00 8D 8D 8D 8D 00 00 00 00 00 00 00

+

characteristics:  045x: C2 00 00 00 00 C2 C2 C3 C3 00 00 00 00 00 00 00

+

Y position:       046x: 4C 00 00 00 00 B4 B4 64 B4 00 00 00 00 00 00 00

+

Y subpixel:       047x: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

X position:       048x: 50 00 00 00 00 79 B9 CC CC 00 00 00 00 00 00 00

+

X subpixel:       049x: 80 00 00 00 00 C0 C0 C0 00 00 00 00 00 00 00 00

+

Not used:         04ax: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

Y pix speed:      04bx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

Y subpix speed:   04cx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

Not used:         04dx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+

X pix speed:      04ex: 00 00 00 00 00 01 01 FE FE 00 00 00 00 00 00 00

+

X subpix speed:   04fx: 00 00 00 00 00 60 60 A0 A0 00 00 00 00 00 00 00

+


+

P = current turtle (player)

+

W = weapon (up to 3 on the screen at one time)

+

E = enemy (up to 8 on the screen at one time)

+

X = no use

+


+

E1 = "Enemy slot 1" which will be the first enemy on the screen loaded into memory.  The 2nd will be placed in "Enemy slot 2".  When enemy 1 is removed from memory (killed or goes off screen), the next enemy will be loaded into that slot.  Enemy's always take the lowest available slot when loaded.  Note: usually enemy slots are in reverse order.  So the first addresses is usually the last enemy slot loaded into memory.  TMNT is an exception.

+


+

All object (player, weapon, enemy) characteristics reside in block 4.

+

Each row is a different characteristic of each object on the screen (040x refers to a sprite ID of an object)

+

Each column corresponds to a specific object on the screen.  (All 04x0 's refer to the player).

+


+

See also, Memory Watch, Hex Editor, Cheat Search, Ram Filter, Movie Making, Tool Assisted Speedruns

+


+


+

+

Created with the Personal Edition of HelpNDoc: Easy CHM and documentation editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NESScrolling1.html b/web/help/NESScrolling1.html index 166ba59f..9488442f 100644 --- a/web/help/NESScrolling1.html +++ b/web/help/NESScrolling1.html @@ -1,126 +1,317 @@ - - + + + + + - NES Scrolling 1 - - - - - - - - - - + + + + + + + + NES Scrolling 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NES Scrolling 1

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Subject: [nesdev] the skinny on nes scrolling

-

Date: Tue, 13 Apr 1999 16:42:00 -0600

-

From: loopy <zxcvzxcv@netzero.net>

-

Reply-To: nesdev@onelist.com

-

To: nesdev@onelist.com

-


-

From: loopy <zxcvzxcv@netzero.net>

-


-

---------

-

the current information on background scrolling is sufficient for most games;

-

however, there are a few that require a more complete understanding.

-


-

here are the related registers:

-

       (v) vram address, a.k.a. 2006 which we all know and love.  (16 bits)

-

       (t) another temp vram address (16 bits)

-

          (you can really call them 15 bits, the last isn't used)

-

      (x) tile X offset (3 bits)

-


-

the ppu uses the vram address for both reading/writing to vram thru 2007,

-

and for fetching nametable data to draw the background.  as it's drawing the

-

background, it updates the address to point to the nametable data currently

-

being drawn.  bits 0-11 hold the nametable address (-$2000).  bits 12-14 are

-

the tile Y offset.

-


-

---------

-

stuff that affects register contents:

-

(sorry for the shorthand logic but i think it's easier to see this way)

-


-

2000 write:

-

       t:0000110000000000=d:00000011

-

2005 first write:

-

       t:0000000000011111=d:11111000

-

       x=d:00000111

-

2005 second write:

-

       t:0000001111100000=d:11111000

-

       t:0111000000000000=d:00000111

-

2006 first write:

-

       t:0011111100000000=d:00111111

-

       t:1100000000000000=0

-

2006 second write:

-

       t:0000000011111111=d:11111111

-

       v=t

-

scanline start (if background and sprites are enabled):

-

       v:0000010000011111=t:0000010000011111

-

frame start (line 0) (if background and sprites are enabled):

-

       v=t

-


-

note!  2005 and 2006 share the toggle that selects between first/second

-

writes.  reading 2002 will clear it.

-


-

note!  all of this info agrees with the tests i've run on a real nes.  BUT

-

if there's something you don't agree with, please let me know so i can verify

-

it.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Free EPub and documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NES Scrolling 1

+ +
+ +

+

Subject: [nesdev] the skinny on nes scrolling

+

Date: Tue, 13 Apr 1999 16:42:00 -0600

+

From: loopy <zxcvzxcv@netzero.net>

+

Reply-To: nesdev@onelist.com

+

To: nesdev@onelist.com

+


+

From: loopy <zxcvzxcv@netzero.net>

+


+

---------

+

the current information on background scrolling is sufficient for most games;

+

however, there are a few that require a more complete understanding.

+


+

here are the related registers:

+

        (v) vram address, a.k.a. 2006 which we all know and love.  (16 bits)

+

        (t) another temp vram address (16 bits)

+

           (you can really call them 15 bits, the last isn't used)

+

       (x) tile X offset (3 bits)

+


+

the ppu uses the vram address for both reading/writing to vram thru 2007,

+

and for fetching nametable data to draw the background.  as it's drawing the

+

background, it updates the address to point to the nametable data currently

+

being drawn.  bits 0-11 hold the nametable address (-$2000).  bits 12-14 are

+

the tile Y offset.

+


+

---------

+

stuff that affects register contents:

+

(sorry for the shorthand logic but i think it's easier to see this way)

+


+

2000 write:

+

        t:0000110000000000=d:00000011

+

2005 first write:

+

        t:0000000000011111=d:11111000

+

        x=d:00000111

+

2005 second write:

+

        t:0000001111100000=d:11111000

+

        t:0111000000000000=d:00000111

+

2006 first write:

+

        t:0011111100000000=d:00111111

+

        t:1100000000000000=0

+

2006 second write:

+

        t:0000000011111111=d:11111111

+

        v=t

+

scanline start (if background and sprites are enabled):

+

        v:0000010000011111=t:0000010000011111

+

frame start (line 0) (if background and sprites are enabled):

+

        v=t

+


+

note!  2005 and 2006 share the toggle that selects between first/second

+

writes.  reading 2002 will clear it.

+


+

note!  all of this info agrees with the tests i've run on a real nes.  BUT

+

if there's something you don't agree with, please let me know so i can verify

+

it.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Qt Help documentation made easy

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NESScrolling2.html b/web/help/NESScrolling2.html index f1b50537..bd1af2cd 100644 --- a/web/help/NESScrolling2.html +++ b/web/help/NESScrolling2.html @@ -1,96 +1,287 @@ - - + + + + + - NES Scrolling 2 - - - - - - - - - - + + + + + + + + NES Scrolling 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NES Scrolling 2

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

nes scrolling

-


-

Date: Tue, 13 Apr 1999 17:48:54 -0600

-

From: loopy <zxcvzxcv@netzero.net>

-

Reply-To: nesdev@onelist.com

-

To: nesdev@onelist.com

-


-

From: loopy <zxcvzxcv@netzero.net>

-


-

(more notes on ppu logic)

-


-

you can think of bits 0,1,2,3,4 of the vram address as the "x scroll"(*8)

-

that the ppu increments as it draws.  as it wraps from 31 to 0, bit 10 is

-

switched.  you should see how this causes horizontal wrapping between name

-

tables (0,1) and (2,3).

-


-

you can think of bits 5,6,7,8,9 as the "y scroll"(*8).  this functions

-

slightly different from the X.  it wraps to 0 and bit 11 is switched when

-

it's incremented from _29_ instead of 31.  there are some odd side effects

-

from this.. if you manually set the value above 29 (from either 2005 or

-

2006), the wrapping from 29 obviously won't happen, and attrib data will be

-

used as name table data.  the "y scroll" still wraps to 0 from 31, but

-

without switching bit 11.  this explains why writing 240+ to 'Y' in 2005

-

appeared as a negative scroll value.

-


-

-

Created with the Personal Edition of HelpNDoc: Free help authoring tool

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NES Scrolling 2

+ +
+ +

+

nes scrolling

+


+

Date: Tue, 13 Apr 1999 17:48:54 -0600

+

From: loopy <zxcvzxcv@netzero.net>

+

Reply-To: nesdev@onelist.com

+

To: nesdev@onelist.com

+


+

From: loopy <zxcvzxcv@netzero.net>

+


+

(more notes on ppu logic)

+


+

you can think of bits 0,1,2,3,4 of the vram address as the "x scroll"(*8)

+

that the ppu increments as it draws.  as it wraps from 31 to 0, bit 10 is

+

switched.  you should see how this causes horizontal wrapping between name

+

tables (0,1) and (2,3).

+


+

you can think of bits 5,6,7,8,9 as the "y scroll"(*8).  this functions

+

slightly different from the X.  it wraps to 0 and bit 11 is switched when

+

it's incremented from _29_ instead of 31.  there are some odd side effects

+

from this.. if you manually set the value above 29 (from either 2005 or

+

2006), the wrapping from 29 obviously won't happen, and attrib data will be

+

used as name table data.  the "y scroll" still wraps to 0 from 31, but

+

without switching bit 11.  this explains why writing 240+ to 'Y' in 2005

+

appeared as a negative scroll value.

+


+

+

Created with the Personal Edition of HelpNDoc: Free Kindle producer

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NESSound.html b/web/help/NESSound.html index 5ccb8687..d8710f8d 100644 --- a/web/help/NESSound.html +++ b/web/help/NESSound.html @@ -1,622 +1,813 @@ - - + + + + + - NES Sound - - - - - - - - - - + + + + + + + + NES Sound + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NES Sound

- -
- Technical Information ›› Sound ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

*******************************************

-

*2A03 sound channel hardware documentation*

-

*******************************************

-

Brad Taylor (big_time_software@hotmail.com)

-


-

4th release:        February 19th, 2K3

-


-


-

All results were obtained by studying prior information available (from nestech 1.00, and postings on NESDev from miscellanious people), and through a series of experiments conducted by me. Results acquired by individuals prior to my reverse-engineering have been double checked, and final results have been confirmed. Credit is due to those individual(s) who contributed miscellanious information in regards to NES sound channel hardware. Such individuals are:

-


-

Goroh

-

Memblers

-

FluBBa

-

Izumi

-

Chibi-Tech

-

Quietust

-

SnowBro

-


-

Kentaro Ishihara (Ki) is responsible for posting (on the NESdev mailing list) differrences in the 2 square wave channels, including the operation of 2A03 hardware publically undocumented (until now) such as the frame IRQ counter, and it's ties with sound hardware. Goroh had originally discovered some of this information, and Ki confirmed it.

-


-

A special thanks goes out to Matthew Conte, for his expertise on pseudo-random number generation (amoung other things), which allowed for the full reverse engineering of the NES's noise channel to take place. Without his help, I would still be trying to find a needle in a haystack, as far as the noise's method of pseudo-random number generation goes. Additionally, his previous findings / reverse engineering work on the NES's sound hardware really got the ball of NES sound emulation rolling. If it weren't for Matt's original work, this document wouldn't exist.

-


-


-

****************

-

* Introduction *

-

****************

-

The 2A03 (NES's integrated CPU) has 4 internal channels to it that have the ability to generate semi-analog sound, for musical playback purposes. These channels are 2 square wave channels, one triangle wave channel, and a noise generation channel. This document will go into full detail on every aspect of the operation and timing of the mentioned sound channels.

-


-


-

*******************

-

* Channel details *

-

*******************

-

Each channel has different characteristics to it that make up it's operation.

-


-

The square channel(s) have the ability to generate a square wave frequency in the range of 54.6 Hz to 12.4 KHz. It's key features are frequency sweep abilities, and output duty cycle adjustment.

-


-

The triangle wave channel has the ability to generate an output triangle wave with a resolution of 4-bits (16 steps), in the range of 27.3 Hz to 55.9 KHz. The key features this channel has is it's analog triangle wave output, and it's linear counter, which can be set to automatically disable the channel's sound after a certain period of time has gone by.

-


-

The noise channel is used for producing random frequencys, which results in a "noisey" sounding output. Output frequencys can range anywhere from 29.3 Hz to 447 KHz. It's key feature is it's pseudo- random number generator, which generates the random output frequencys heard by the channel.

-


-


-

*****************

-

* Frame counter *

-

*****************

-

The 2A03 has an internal frame counter. The purpose of it is to generate the various low frequency signals (60, 120, 240 Hz, and 48, 96, 192 Hz) required to clock several of the sound hardware's counters. It also has the ability to generate IRQ's.

-


-

The smallest unit of timing the frame counter operates around is 240Hz; all other frequencies are generated by multiples of this base frequency. A clock divider of 14915 (clocked at twice the CPU speed) is used to get 240Hz (this was the actual measured ratio).

-


-


-

+---------------+

-

|$4017 operation|

-

+---------------+

-

Writes to register $4017 control operation of both the clock divider, and the frame counter.

-


-

- Any write to $4017 resets both the frame counter, and the clock divider. Sometimes, games will write to this register in order to synchronize the sound hardware's internal timing, to the sound routine's timing (usually tied into the NMI code). The frame IRQ is slightly longer than the PPU's, so you can see why games would desire this syncronization.

-


-

- bit 7 of $4017 controls the frame counter's divide rate. Every time the counter cycles (reaches terminal count (0)), a frame IRQ will be generated, if enabled by clearing bit 6 of $4017. $4015.6 holds the status of the frame counter IRQ; it will be set if the frame counter is responsible for the interrupt.

-


-

$4017.7  divider  frame IRQ freq.

-

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

-

0        4        60

-

1        5        48

-


-

On 2A03 reset, both bits of $4017 (6 & 7) will be cleared, enabling frame IRQ's off the hop. The reason why the existence of frame IRQ's are generally unknown is because the 6502's maskable interrupt is disabled on reset, and this blocks out the frame IRQ's. Most games don't use any IRQ-generating hardware in general, therefore they don't bother enabling maskable interrupts.

-


-

Note that the IRQ line will be held down by the frame counter until it is acknowledged (by reading $4015). Before this, the 6502 will generate an IRQ *every* time interrupts are enabled (either by CLI or RTI), since the IRQ design on the 6502 is level-triggered, and not edge. If you've written a program that does not read $4015 in the IRQ handler, and you execute CLI, the processor will immediately go into a infinite IRQ call-return loop.

-


-


-

+-----------------------+

-

|Frame counter operation|

-

+-----------------------+

-

Depending on the status of $4017.7, the frame counter will follow 2 different count sequences. These sequences determine when sound hardware counters will be clocked. The sequences are initialized immediately following any write to $4017.

-


-

$4017.7  sequence

-

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

-

0        4, 0,1,2,3, 0,1,2,3,..., etc.

-

1        0,1,2,3,4, 0,1,2,3,4,..., etc.

-


-

During count sequences 0..3, the linear (triangle) and envelope decay (square & noise) counters recieve a clock for each count. This means that both these counters are clocked once immediately after $4017.7 is written with a value of 1.

-


-

Count sequences 1 & 3 clock (update) the frequency sweep (square), and length (all channels) counters. Even though the length counter's smallest unit of time counting is a frame, it seems that it is actually being clocked twice per frame. That said, you can consider the length counters to contain an extra stage to divide this clock signal by 2.

-


-

No aforementioned sound hardware counters are clocked on count sequence #4. You should now see how this causes the 96, and 192 Hz signals to be generated when $4017.7=1.

-


-

The rest of the document will describe the operation of the sound channels using the $4017.7=0 frequencies (60, 120, and 240 Hz). For $4017.7=1 operation, replace those frequencies with 48, 96, and 192 Hz (respectively).

-


-


-

************************

-

* Sound hardware delay *

-

************************

-

After resetting the 2A03, the first time any sound channel(s) length counter contains a non-zero value (channel is enabled), there will be a 2048 CPU clock cycle delay before any of the sound hardware is clocked. After the 2K clock cycles go by, the NES sound hardware will be clocked normally. This phenomenon only occurs prior to a system reset, and only occurs during the first 2048 CPU clocks after the activation of any of the 4 basic sound channels.

-


-

The information in regards to this delay is only provided to keep this document accurate with all information that is currently known about the 2A03's sound hardware. I haven't done much tests on the behaviour of this delay (mainly because I don't care, as I view it as a inconvenience anyway), so this information should be taken with a grain of salt.

-


-


-

************************

-

* Register Assignments *

-

************************

-

The sound hardware internal to the 2A03 has been designated these special memory addresses in the CPU's memory map.

-


-

$4000-$4003        Square wave 1

-

$4004-$4007        Square wave 2 (identical to the first, except for upward frequency sweeps (see "sweep unit" section))

-

$4008-$400B        Triangle

-

$400C-$400F        Noise

-

$4015                Channel enable / length/frame counter status

-

$4017                frame counter control

-


-

Note that $4015 (and $4017, but is unrelated to sound hardware) are the only R/W registers. All others are write only (attempt to read them will most likely return the last byte on the bus (usually 040H), due to heavy capacitance on the NES's data bus). Reading a "write only" register, will have no effect on the specific register, or channel.

-


-

Every sound channel has 4 registers affiliated with it. The description of the register sets are as follows:

-


-

+----------------+

-

| Register set 1 |

-

+----------------+

-


-

$4000(sq1)/$4004(sq2)/$400C(noise) bits

-

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

-

0-3        volume / envelope decay rate

-

4        envelope decay disable

-

5        length counter clock disable / envelope decay looping enable

-

6-7        duty cycle type (unused on noise channel)

-


-

$4008(tri) bits

-

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

-

0-6        linear counter load register

-

7        length counter clock disable / linear counter start

-


-


-

+----------------+

-

| Register set 2 |

-

+----------------+

-


-

$4001(sq1)/$4005(sq2) bits

-

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

-

0-2        right shift amount

-

3        decrease / increase (1/0) wavelength

-

4-6        sweep update rate

-

7        sweep enable

-


-

$4009(tri)/$400D(noise) bits

-

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

-

0-7        unused

-


-


-

+----------------+

-

| Register set 3 |

-

+----------------+

-


-

$4002(sq1)/$4006(sq2)/$400A(Tri) bits

-

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

-

0-7        8 LSB of wavelength

-


-

$400E(noise) bits

-

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

-

0-3        playback sample rate

-

4-6        unused

-

7        random number type generation

-


-


-

+----------------+

-

| Register set 4 |

-

+----------------+

-


-

$4003(sq1)/$4007(sq2)/$400B(tri)/$400F(noise) bits

-

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

-

0-2        3 MS bits of wavelength (unused on noise channel)

-

3-7        length counter load register

-


-


-

+--------------------------------+

-

| length counter status register |

-

+--------------------------------+

-


-

$4015(read)

-

-----------

-

0        square wave channel 1

-

1        square wave channel 2

-

2        triangle wave channel

-

3        noise channel

-

4        DMC (see "DMC.TXT" for details)

-

5-6        unused

-

7        IRQ status of DMC (see "DMC.TXT" for details)

-


-


-

+-------------------------+

-

| channel enable register |

-

+-------------------------+

-


-

$4015(write)

-

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

-

0        square wave channel 1

-

1        square wave channel 2

-

2        triangle wave channel

-

3        noise channel

-

4        DMC channel (see "DMC.TXT" for details)

-

5-7        unused

-


-


-

************************

-

* Channel architecture *

-

************************

-

This section will describe the internal components making up each individual channel. Each component will then be described in full detail.

-


-

Device                                 Triangle Noise  Square

-

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

-

triangle step generator                        X

-

linear counter                                X

-

programmable timer                        X      X      X

-

length counter                                X      X      X

-

4-bit DAC                                        X      X      X

-

volume/envelope decay unit                         X      X

-

sweep unit                                                          X

-

duty cycle generator                                          X

-

wavelength converter                                 X

-

random number generator                                 X

-


-


-

+-------------------------+

-

| Triangle step generator |

-

+-------------------------+

-

This is a 5-bit, single direction counter, and it is only used in the triangle channel. Each of the 4 LSB outputs of the counter lead to one input on a corresponding mutually exclusive XNOR gate. The 4 XNOR gates have been strobed together, which results in the inverted representation of the 4 LSB of the counter appearing on the outputs of the gates when the strobe is 0, and a non-inverting action taking place when the strobe is 1. The strobe is naturally connected to the MSB of the counter, which effectively produces on the output of the XNOR gates a count sequence which reflects the scenario of a near- ideal triangle step generator (D,E,F,F,E,D,...,2,1,0,0,1,2,...). At this point, the outputs of the XNOR gates will be fed into the input of a 4-bit DAC.

-


-

This 5-bit counter will be halted whenever the Triangle channel's length or linear counter contains a count of 0. This results in a "latching" behaviour; the counter will NOT be reset to any definite state.

-


-

On system reset, this counter is loaded with 0.

-


-

The counter's clock input is connected directly to the terminal count output pin of the 11-bit programmable timer in the triangle channel. As a result of the 5-bit triangle step generator, the output triangle wave frequency will be 32 times less than the frequency of the triangle channel's programmable timer is set to generate.

-


-


-

+----------------+

-

| Linear counter |

-

+----------------+

-

The linear counter is only found in the triangle channel. It is a 7-bit presettable down counter, with a decoded output condition of 0 available (not exactly the same as terminal count). Here's the bit assignments:

-


-

$4008 bits

-

----------

-

0-6        bits 0-6 of the linear counter load register (NOT the linear counter itself)

-

7        linear counter start

-


-

The counter is clocked at 240 Hz (1/4 framerate), and the calculated length in frames is 0.25*N, where N is the 7-bit loaded value. The counter is always being clocked, except when 0 appears on the output of the counter. At this point, the linear counter & triangle step counter clocks signals are disabled, which results in both counters latching their current state (the linear counter will stay at 0, and the triangle step counter will stop, and the channel will be silenced due to this).

-


-

The linear counter has 2 modes: load, and count. When the linear counter is in load mode, it essentially becomes transparent (i.e. whatever value is currently in, or being written to $4008, will appear on the output of the counter). Because of this, no count action can occur in load mode. When the mode changes from load to count, the counter will now latch the value currently in it, and start counting down from there. In the count mode, the current value of $4008 is ignored by the counter (but still retained in $4008). Described below is how the mode of the linear counter is set:

-


-


-

Writes to $400B

-

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

-

cur        mode

-

---        ----

-

1        load

-

0        load (on next linear counter clock), count

-


-

Cur is the current state of the MSB of $4008.

-


-


-

Writes to $4008

-

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

-

old        new        mode

-

---        ---        ----

-

0        X        count

-

1        0        no change (during the CPU write cycle), count

-

1        1        no change

-


-

Old and new represent the state(s) of the MSB of $4008. Old is the value being replaced in the MSB of $4008 on the write, and new is the value replacing the old one.

-


-

"no change" indicates that the mode of the linear counter will not change from the last.

-


-

Note that writes to $400B when $4008.7=0 only loads the linear counter with the value in $4008 on the next *linear* counter clock (and NOT at the end of the CPU write cycle). This is a correction from older versions of this doc.

-


-


-

+--------------------+

-

| Programmable timer |

-

+--------------------+

-

The programmable timer is a 11-bit presettable down counter, and is found in the square, triangle, and noise channel(s). The bit assignments are as follows:

-


-

$4002(sq1)/$4006(sq2)/$400A(Tri) bits

-

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

-

0-7        represent bits 0-7 of the 11-bit wavelength

-


-

$4003(sq1)/$4007(sq2)/$400B(Tri) bits

-

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

-

0-2        represent bits 8-A of the 11-bit wavelength

-


-

Note that on the noise channel, the 11 bits are not available directly. See the wavelength converter section, for more details.

-


-

The counter has automatic syncronous reloading upon terminal count (count=0), therefore the counter will count for N+1 (N is the 11-bit loaded value) clock cycles before arriving at terminal count, and reloading. This counter will typically be clocked at the 2A03's internal 6502 speed (1.79 MHz), and produces an output frequency of 1.79 MHz/(N+1). The terminal count's output spike length is typically no longer than half a CPU clock. The TC signal will then be fed to the appropriate device for the particular sound channel (for square, this terminal count spike will lead to the duty cycle generator. For the triangle, the spike will be fed to the triangle step generator. For noise, this signal will go to the random number generator unit).

-


-


-

+----------------+

-

| Length counter |

-

+----------------+

-

The length counter is found in all sound channels. It is essentially a 7-bit down counter, and is conditionally clocked at a frequency of 60 Hz.

-


-

When the length counter arrives at a count of 0, the counter will be stopped (stay on 0), and the appropriate channel will be silenced.

-


-

The length counter clock disable bit, found in all the channels, can also be used to halt the count sequence of the length counter for the appropriate channel, by writing a 1 out to it. A 0 condition will permit counting (unless of course, the counter's current count = 0). Location(s) of the length counter clock disable bit:

-


-

$4000(sq1)/$4004(sq2)/$400C(noise) bits

-

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

-

5        length counter clock disable

-


-

$4008(tri) bits

-

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

-

7        length counter clock disable

-


-

To load the length counter with a specified count, a write must be made out to the length register. Location(s) of the length register:

-


-

$4003(sq1)/$4007(sq2)/$400B(tri)/$400F(noise) bits

-

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

-

3-7        length

-


-

The 5-bit length value written, determines what 7-bit value the length counter will start counting from. A conversion table here will show how the values are translated.

-


-

       +-----------------------+

-

       |        bit3=0        |

-

       +-------+---------------+

-

       |        |frames                |

-

       |bits        +-------+-------+

-

       |4-6        |bit7=0        |bit7=1        |

-

       +-------+-------+-------+

-

       |0        |05        |06        |

-

       |1        |0A        |0C        |

-

       |2        |14        |18        |

-

       |3        |28        |30        |

-

       |4        |50        |60        |

-

       |5        |1E        |24        |

-

       |6        |07        |08        |

-

       |7        |0D        |10        |

-

       +-------+-------+-------+

-


-

       +---------------+

-

       |        bit3=1        |

-

       +-------+-------+

-

       |bits        |        |

-

       |4-7        |frames        |

-

       +-------+-------+

-

       |0        |7F        |

-

       |1        |01        |        

-

       |2        |02        |

-

       |3        |03        |

-

       |4        |04        |

-

       |5        |05        |

-

       |6        |06        |

-

       |7        |07        |

-

       |8        |08        |

-

       |9        |09        |

-

       |A        |0A        |

-

       |B        |0B        |

-

       |C        |0C        |

-

       |D        |0D        |

-

       |E        |0E        |

-

       |F        |0F        |

-

       +-------+-------+

-


-

The length counter's real-time status for each channel can be attained. A 0 is returned for a zero count status in the length counter (channel's sound is disabled), and 1 for a non-zero status. Here's the bit description of the length counter status register:

-


-

$4015(read)

-

-----------

-

0        length counter status of square wave channel 1

-

1        length counter status of square wave channel 2

-

2        length counter status of triangle wave channel

-

3        length counter status of noise channel

-

4        length counter status of DMC (see "DMC.TXT" for details)

-

5        unknown

-

6        frame IRQ status

-

7        IRQ status of DMC (see "DMC.TXT" for details)

-


-

Writing a 0 to the channel enable register will force the length counters to always contain a count equal to 0, which renders that specific channel disabled (as if it doesn't exist). Writing a 1 to the channel enable register disables the forced length counter value of 0, but will not change the count itself (it will still be whatever it was prior to the writing of 1).

-


-

Bit description of the channel enable register:

-


-

$4015(write)

-

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

-

0        enable square wave channel 1

-

1        enable square wave channel 2

-

2        enable triangle wave channel

-

3        enable noise channel

-

4        enable DMC channel (see "DMC.TXT" for details)

-

5-7        unknown

-


-

Note that all 5 used bits in this register will be set to 0 upon system reset.

-


-


-

+-----------+

-

| 4-bit DAC |

-

+-----------+

-

This is just a standard 4-bit DAC with 16 steps of output voltage resolution, and is used by all 4 sound channels. On the 2A03, square wave 1 & 2 are mixed together, and are available via pin 1. Triangle & noise are available on pin 2.

-


-

These analog outputs require a negative current source, to attain linear symmetry on the various output voltage levels generated by the channel(s) (moreover, to get the sound to be audible). Instead of current sources, the NES uses external 100 ohm pull-down resistors. This results in the output waveforms having some linear asymmetry (i.e., as the desired output voltage increases on a linear scale, the actual outputted voltage increases less and less each step).

-


-

The side effect of this is that the DMC's 7-bit DAC port ($4011) is able to indirectly control the volume (somewhat) of both triangle & noise channels. While I have not measured the voltage asymmetery, others on the NESdev messageboards have posted their findings. The conclusion is that when $4011 is 0, triangle & noise volume outputs are at maximum. When $4011 = 7F, the triangle & noise channel outputs operate at only 57% total volume.

-


-

The odd thing is that a few games actually take advantage of this "volume" feature, and write values to $4011 in order to regulate the amplitude of the triangle wave channel's output.

-


-


-

+------------------------------+

-

| Volume / envelope decay unit |

-

+------------------------------+

-

The volume / envelope decay hardware is found only in the square wave and noise channels.

-


-

$4000(sq1)/$4004(sq2)/$400C(noise)

-

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

-

0-3        volume / envelope decay rate

-

4        envelope decay disable

-

5        envelope decay looping enable

-


-

When the envelope decay disable bit (bit 4) is set (1), the current volume value (bits 0-3) is sent directly to the channel's DAC. However, depending on certain conditions, this 4-bit volume value will be ignored, and a value of 0 will be sent to the DAC instead. This means that while the channel is enabled (producing sound), the output of the channel (what you'll hear from the DAC) will either be the 4-bit volume value, or 0. This also means that a 4-bit volume value of 0 will result in no audible sound. These conditions are as follows:

-


-

- When hardware in the channel wants to disable it's sound output (like the length counter, or sweep unit (square channels only)).

-


-

- On the negative portion of the output frequency signal coming from the duty cycle / random number generator hardware (square wave channel / noise channel).

-


-

When the envelope decay disable bit is cleared, bits 0-3 now control the envelope decay rate, and an internal 4-bit down counter (hereon the envelope decay counter) now controls the channel's volume level. "Envelope decay" is used to describe the action of the channel's audio output volume starting from a certain value, and decreasing by 1 at a fixed (linear) rate (which produces a "fade-out" sounding effect). This fixed decrement rate is controlled by the envelope decay rate (bits 0-3). The calculated decrement rate is 240Hz/(N+1), where N is any value between $0-$F.

-


-

When the channel's envelope decay counter reaches a value of 0, depending on the status of the envelope decay looping enable bit (bit 5, which is shared with the length counter's clock disable bit), 2 different things will happen:

-


-

bit 5        action

-

-----        ------

-

0        The envelope decay count will stay at 0 (channel silenced).

-

1        The envelope decay count will wrap-around to $F (upon the next clock cycle). The envelope decay counter will then continue to count down normally.

-


-

Only a write out to $4003/$4007/$400F will reset the current envelope decay counter to a known state (to $F, the maximum volume level) for the appropriate channel's envelope decay hardware. Otherwise, the envelope decay counter is always counting down (by 1) at the frequency currently contained in the volume / envelope decay rate bits (even when envelope decays are disabled (setting bit 4)), except when the envelope decay counter contains a value of 0, and envelope decay looping (bit 5) is disabled (0).

-


-


-

+------------+

-

| Sweep unit |

-

+------------+

-

The sweep unit is only found in the square wave channels. The controls for the sweep unit have been mapped in at $4001 for square 1, and $4005 for square 2.

-


-

The controls

-

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

-

Bit 7          when this bit is set (1), sweeping is active. This results in real-time increasing or decreasing of the the current wavelength value (the audible frequency will decrease or increase, respectively). The wavelength value in $4002/3 ($4006/7) is constantly read & updated by the sweep. Modifying the contents of $4002/3 will be immediately audible, and will result in the sweep now starting from this new wavelength value.

-


-

Bits 6-4        These 3 bits represent the sweep refresh rate, or the frequency at which $4002/3 is updated with the new calculated wavelength. The refresh rate frequency is 120Hz/(N+1), where N is the value written, between 0 and 7.

-


-

Bit 3          This bit controls the sweep mode. When this bit is set (1), sweeps will decrease the current wavelength value, as a 0 will increase the current wavelength.

-


-

Bits 2-0        These bits control the right shift amount of the new calculated sweep update wavelength. Code that shows how the sweep unit calculates a new sweep wavelength is as follows:

-

-

bit 3

-

-----

-

0        New = Wavelength + (Wavelength >> N)

-

1        New = Wavelength - (Wavelength >> N) (minus an additional 1, if using square wave channel 1)

-


-

where N is the the shift right value, between 0-7.

-


-

Note that in decrease mode, for subtracting the 2 values:

-

1's compliment (NOT) is being used for square wave channel 1

-

2's compliment (NEG) is being used for square wave channel 2

-


-

This information is currently the only known difference between the 2 square wave channels.

-


-

On each sweep refresh clock, the Wavelength register will be updated with the New value, but only if all 3 of these conditions are met:

-


-

- bit 7 is set (sweeping enabled)

-

- the shift value (which is N in the formula) does not equal to 0

-

- the channel's length counter contains a non-zero value

-


-

Notes

-

-----

-

There are certain conditions that will cause the sweep unit to silence the channel, and halt the sweep refresh clock (which effectively stops sweep action, if any). Note that these conditions pertain regardless of any sweep refresh rate values, or if sweeping is enabled/disabled (via bit 7).

-


-

- an 11-bit wavelength value less than $008 will cause this condition

-

- if the sweep unit is currently set to increase mode, the New calculated wavelength value will always be tested to see if a carry (bit $B) was generated or not (if sweeping is enabled, this carry will be examined before the Wavelength register is updated) from the shift addition calculation. If carry equals 1, the channel is silenced, and sweep action is halted.

-


-


-

+----------------------+

-

| Duty cycle generator |

-

+----------------------+

-

The duty cycle generator takes the fequency produced from the 11-bit programmable timer, and uses a 4 bit counter to produce 4 types of duty cycles. The output frequency is then 1/16 that of the programmable timer. The duty cycle hardware is only found in the square wave channels. The bit assignments are as follows:

-


-

$4000(sq1)/$4004(sq2)

-

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

-

6-7        Duty cycle type

-


-

       duty (positive/negative)

-

val        in clock cycles

-

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

-

00         2/14

-

01         4/12

-

10         8/ 8

-

11        12/ 4

-


-

Where val represents bits 6-7 of $4000/$4004.

-


-

This counter is reset when the length counter of the same channel is written to (via $4003/$4007).

-


-

The output frequency at this point will now be fed to the volume/envelope decay hardware.

-


-


-

+----------------------+

-

| Wavelength converter |

-

+----------------------+

-

The wavelength converter is only used in the noise channel. It is used to convert a given 4-bit value to an 11-bit wavelength, which then is sent to the noise's own programmable timer. Here is the bit descriptions:

-


-

$400E bits

-

----------

-

0-3        The 4-bit value to be converted

-


-

Below is a conversion chart that shows what 4-bit value will represent the 11-bit wavelength to be fed to the channel's programmable timer:

-


-

value        octave        scale        CPU clock cycles (11-bit wavelength+1)

-

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

-

0        15        A        002

-

1        14        A        004

-

2        13        A        008

-

3        12        A        010

-

4        11        A        020

-

5        11        D        030

-

6        10        A        040

-

7        10        F        050

-

8        10        C        065

-

9         9        A        07F

-

A         9        D        0BE

-

B         8        A        0FE

-

C         8        D        17D

-

D         7        A        1FC

-

E         6        A        3F9

-

F         5        A        7F2

-


-

Octave and scale information is provided for the music enthusiast programmer who is more familiar with notes than clock cycles.

-


-


-

+-------------------------+

-

| Random number generator |

-

+-------------------------+

-

The noise channel has a 1-bit pseudo-random number generator. It's based on a 15-bit shift register, and an exclusive or gate. The generator can produce two types of random number sequences: long, and short. The long sequence generates 32,767-bit long number patterns. The short sequence generates 93-bit long number patterns. The 93-bit mode will generally produce higher sounding playback frequencys on the channel. Here is the bit that controls the mode:

-


-

$400E bits

-

----------

-

7        mode

-


-

If mode=0, then 32,767-bit long number sequences will be produced (32K mode), otherwise 93-bit long number sequences will be produced (93-bit mode).

-


-

The following diagram shows where the XOR taps are taken off the shift register to produce the 1-bit pseudo-random number sequences for each mode.

-


-

mode            <-----

-

----        EDCBA9876543210

-

32K        **

-

93-bit        *     *

-


-

The current result of the XOR will be transferred into bit position 0 of the SR, upon the next shift cycle. The 1-bit random number output is taken from pin E, is inverted, then is sent to the volume/envelope decay hardware for the noise channel. The shift register is shifted upon recieving 2 clock pulses from the programmable timer (the shift frequency will be half that of the frequency from the programmable timer (one octave lower)).

-


-

On system reset, this shift register is loaded with a value of 1.

-


-


-

RP2A03E quirk

-

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

-

I have been informed that revisions of the 2A03 before "F" actually lacked support for the 93-bit looped noise playback mode. While the Famicom's 2A03 went through 4 revisions (E..H), I think that only one was ever used for the front loading NES: "G". Other differences between 2A03 revisions are unknown.

-


-


-

EOF

-

-

Created with the Personal Edition of HelpNDoc: Create iPhone web-based documentation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NES Sound

+ +
+ +

+

*******************************************

+

*2A03 sound channel hardware documentation*

+

*******************************************

+

Brad Taylor (big_time_software@hotmail.com)

+


+

 4th release:        February 19th, 2K3

+


+


+

 All results were obtained by studying prior information available (from nestech 1.00, and postings on NESDev from miscellanious people), and through a series of experiments conducted by me. Results acquired by individuals prior to my reverse-engineering have been double checked, and final results have been confirmed. Credit is due to those individual(s) who contributed miscellanious information in regards to NES sound channel hardware. Such individuals are:

+


+

 Goroh

+

 Memblers

+

 FluBBa

+

 Izumi

+

 Chibi-Tech

+

 Quietust

+

 SnowBro

+


+

 Kentaro Ishihara (Ki) is responsible for posting (on the NESdev mailing list) differrences in the 2 square wave channels, including the operation of 2A03 hardware publically undocumented (until now) such as the frame IRQ counter, and it's ties with sound hardware. Goroh had originally discovered some of this information, and Ki confirmed it.

+


+

 A special thanks goes out to Matthew Conte, for his expertise on pseudo-random number generation (amoung other things), which allowed for the full reverse engineering of the NES's noise channel to take place. Without his help, I would still be trying to find a needle in a haystack, as far as the noise's method of pseudo-random number generation goes. Additionally, his previous findings / reverse engineering work on the NES's sound hardware really got the ball of NES sound emulation rolling. If it weren't for Matt's original work, this document wouldn't exist.

+


+


+

****************

+

* Introduction *

+

****************

+

 The 2A03 (NES's integrated CPU) has 4 internal channels to it that have the ability to generate semi-analog sound, for musical playback purposes. These channels are 2 square wave channels, one triangle wave channel, and a noise generation channel. This document will go into full detail on every aspect of the operation and timing of the mentioned sound channels.

+


+


+

*******************

+

* Channel details *

+

*******************

+

 Each channel has different characteristics to it that make up it's operation.

+


+

 The square channel(s) have the ability to generate a square wave frequency in the range of 54.6 Hz to 12.4 KHz. It's key features are frequency sweep abilities, and output duty cycle adjustment.

+


+

 The triangle wave channel has the ability to generate an output triangle wave with a resolution of 4-bits (16 steps), in the range of 27.3 Hz to 55.9 KHz. The key features this channel has is it's analog triangle wave output, and it's linear counter, which can be set to automatically disable the channel's sound after a certain period of time has gone by.

+


+

 The noise channel is used for producing random frequencys, which results in a "noisey" sounding output. Output frequencys can range anywhere from 29.3 Hz to 447 KHz. It's key feature is it's pseudo- random number generator, which generates the random output frequencys heard by the channel.

+


+


+

*****************

+

* Frame counter *

+

*****************

+

 The 2A03 has an internal frame counter. The purpose of it is to generate the various low frequency signals (60, 120, 240 Hz, and 48, 96, 192 Hz) required to clock several of the sound hardware's counters. It also has the ability to generate IRQ's.

+


+

 The smallest unit of timing the frame counter operates around is 240Hz; all other frequencies are generated by multiples of this base frequency. A clock divider of 14915 (clocked at twice the CPU speed) is used to get 240Hz (this was the actual measured ratio).

+


+


+

+---------------+

+

|$4017 operation|

+

+---------------+

+

 Writes to register $4017 control operation of both the clock divider, and the frame counter.

+


+

 - Any write to $4017 resets both the frame counter, and the clock divider. Sometimes, games will write to this register in order to synchronize the sound hardware's internal timing, to the sound routine's timing (usually tied into the NMI code). The frame IRQ is slightly longer than the PPU's, so you can see why games would desire this syncronization.

+


+

 - bit 7 of $4017 controls the frame counter's divide rate. Every time the counter cycles (reaches terminal count (0)), a frame IRQ will be generated, if enabled by clearing bit 6 of $4017. $4015.6 holds the status of the frame counter IRQ; it will be set if the frame counter is responsible for the interrupt.

+


+

$4017.7  divider  frame IRQ freq.

+

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

+

0        4        60

+

1        5        48

+


+

 On 2A03 reset, both bits of $4017 (6 & 7) will be cleared, enabling frame IRQ's off the hop. The reason why the existence of frame IRQ's are generally unknown is because the 6502's maskable interrupt is disabled on reset, and this blocks out the frame IRQ's. Most games don't use any IRQ-generating hardware in general, therefore they don't bother enabling maskable interrupts.

+


+

 Note that the IRQ line will be held down by the frame counter until it is acknowledged (by reading $4015). Before this, the 6502 will generate an IRQ *every* time interrupts are enabled (either by CLI or RTI), since the IRQ design on the 6502 is level-triggered, and not edge. If you've written a program that does not read $4015 in the IRQ handler, and you execute CLI, the processor will immediately go into a infinite IRQ call-return loop.

+


+


+

+-----------------------+

+

|Frame counter operation|

+

+-----------------------+

+

 Depending on the status of $4017.7, the frame counter will follow 2 different count sequences. These sequences determine when sound hardware counters will be clocked. The sequences are initialized immediately following any write to $4017.

+


+

$4017.7  sequence

+

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

+

0        4, 0,1,2,3, 0,1,2,3,..., etc.

+

1        0,1,2,3,4, 0,1,2,3,4,..., etc.

+


+

 During count sequences 0..3, the linear (triangle) and envelope decay (square & noise) counters recieve a clock for each count. This means that both these counters are clocked once immediately after $4017.7 is written with a value of 1.

+


+

 Count sequences 1 & 3 clock (update) the frequency sweep (square), and length (all channels) counters. Even though the length counter's smallest unit of time counting is a frame, it seems that it is actually being clocked twice per frame. That said, you can consider the length counters to contain an extra stage to divide this clock signal by 2.

+


+

 No aforementioned sound hardware counters are clocked on count sequence #4. You should now see how this causes the 96, and 192 Hz signals to be generated when $4017.7=1.

+


+

 The rest of the document will describe the operation of the sound channels using the $4017.7=0 frequencies (60, 120, and 240 Hz). For $4017.7=1 operation, replace those frequencies with 48, 96, and 192 Hz (respectively).

+


+


+

************************

+

* Sound hardware delay *

+

************************

+

 After resetting the 2A03, the first time any sound channel(s) length counter contains a non-zero value (channel is enabled), there will be a 2048 CPU clock cycle delay before any of the sound hardware is clocked. After the 2K clock cycles go by, the NES sound hardware will be clocked normally. This phenomenon only occurs prior to a system reset, and only occurs during the first 2048 CPU clocks after the activation of any of the 4 basic sound channels.

+


+

 The information in regards to this delay is only provided to keep this document accurate with all information that is currently known about the 2A03's sound hardware. I haven't done much tests on the behaviour of this delay (mainly because I don't care, as I view it as a inconvenience anyway), so this information should be taken with a grain of salt.

+


+


+

************************

+

* Register Assignments *

+

************************

+

 The sound hardware internal to the 2A03 has been designated these special memory addresses in the CPU's memory map.

+


+

$4000-$4003        Square wave 1

+

$4004-$4007        Square wave 2 (identical to the first, except for upward frequency sweeps (see "sweep unit" section))

+

$4008-$400B        Triangle

+

$400C-$400F        Noise

+

$4015                Channel enable / length/frame counter status

+

$4017                frame counter control

+


+

 Note that $4015 (and $4017, but is unrelated to sound hardware) are the only R/W registers. All others are write only (attempt to read them will most likely return the last byte on the bus (usually 040H), due to heavy capacitance on the NES's data bus). Reading a "write only" register, will have no effect on the specific register, or channel.

+


+

 Every sound channel has 4 registers affiliated with it. The description of the register sets are as follows:

+


+

+----------------+

+

| Register set 1 |

+

+----------------+

+


+

$4000(sq1)/$4004(sq2)/$400C(noise) bits

+

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

+

0-3        volume / envelope decay rate

+

4        envelope decay disable

+

5        length counter clock disable / envelope decay looping enable

+

6-7        duty cycle type (unused on noise channel)

+


+

$4008(tri) bits

+

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

+

0-6        linear counter load register

+

7        length counter clock disable / linear counter start

+


+


+

+----------------+

+

| Register set 2 |

+

+----------------+

+


+

$4001(sq1)/$4005(sq2) bits

+

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

+

0-2        right shift amount

+

3        decrease / increase (1/0) wavelength

+

4-6        sweep update rate

+

7        sweep enable

+


+

$4009(tri)/$400D(noise) bits

+

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

+

0-7        unused

+


+


+

+----------------+

+

| Register set 3 |

+

+----------------+

+


+

$4002(sq1)/$4006(sq2)/$400A(Tri) bits

+

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

+

0-7        8 LSB of wavelength

+


+

$400E(noise) bits

+

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

+

0-3        playback sample rate

+

4-6        unused

+

7        random number type generation

+


+


+

+----------------+

+

| Register set 4 |

+

+----------------+

+


+

$4003(sq1)/$4007(sq2)/$400B(tri)/$400F(noise) bits

+

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

+

0-2        3 MS bits of wavelength (unused on noise channel)

+

3-7        length counter load register

+


+


+

+--------------------------------+

+

| length counter status register |

+

+--------------------------------+

+


+

$4015(read)

+

-----------

+

0        square wave channel 1

+

1        square wave channel 2

+

2        triangle wave channel

+

3        noise channel

+

4        DMC (see "DMC.TXT" for details)

+

5-6        unused

+

7        IRQ status of DMC (see "DMC.TXT" for details)

+


+


+

+-------------------------+

+

| channel enable register |

+

+-------------------------+

+


+

$4015(write)

+

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

+

0        square wave channel 1

+

1        square wave channel 2

+

2        triangle wave channel

+

3        noise channel

+

4        DMC channel (see "DMC.TXT" for details)

+

5-7        unused

+


+


+

************************

+

* Channel architecture *

+

************************

+

 This section will describe the internal components making up each individual channel. Each component will then be described in full detail.

+


+

Device                                 Triangle Noise  Square

+

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

+

triangle step generator                        X

+

linear counter                                X

+

programmable timer                        X      X      X

+

length counter                                X      X      X

+

4-bit DAC                                        X      X      X

+

volume/envelope decay unit                         X      X

+

sweep unit                                                          X

+

duty cycle generator                                          X

+

wavelength converter                                 X

+

random number generator                                 X

+


+


+

+-------------------------+

+

| Triangle step generator |

+

+-------------------------+

+

 This is a 5-bit, single direction counter, and it is only used in the triangle channel. Each of the 4 LSB outputs of the counter lead to one input on a corresponding mutually exclusive XNOR gate. The 4 XNOR gates have been strobed together, which results in the inverted representation of the 4 LSB of the counter appearing on the outputs of the gates when the strobe is 0, and a non-inverting action taking place when the strobe is 1. The strobe is naturally connected to the MSB of the counter, which effectively produces on the output of the XNOR gates a count sequence which reflects the scenario of a near- ideal triangle step generator (D,E,F,F,E,D,...,2,1,0,0,1,2,...). At this point, the outputs of the XNOR gates will be fed into the input of a 4-bit DAC.

+


+

 This 5-bit counter will be halted whenever the Triangle channel's length or linear counter contains a count of 0. This results in a "latching" behaviour; the counter will NOT be reset to any definite state.

+


+

 On system reset, this counter is loaded with 0.

+


+

 The counter's clock input is connected directly to the terminal count output pin of the 11-bit programmable timer in the triangle channel. As a result of the 5-bit triangle step generator, the output triangle wave frequency will be 32 times less than the frequency of the triangle channel's programmable timer is set to generate.

+


+


+

+----------------+

+

| Linear counter |

+

+----------------+

+

 The linear counter is only found in the triangle channel. It is a 7-bit presettable down counter, with a decoded output condition of 0 available (not exactly the same as terminal count). Here's the bit assignments:

+


+

$4008 bits

+

----------

+

0-6        bits 0-6 of the linear counter load register (NOT the linear counter itself)

+

7        linear counter start

+


+

 The counter is clocked at 240 Hz (1/4 framerate), and the calculated length in frames is 0.25*N, where N is the 7-bit loaded value. The counter is always being clocked, except when 0 appears on the output of the counter. At this point, the linear counter & triangle step counter clocks signals are disabled, which results in both counters latching their current state (the linear counter will stay at 0, and the triangle step counter will stop, and the channel will be silenced due to this).

+


+

 The linear counter has 2 modes: load, and count. When the linear counter is in load mode, it essentially becomes transparent (i.e. whatever value is currently in, or being written to $4008, will appear on the output of the counter). Because of this, no count action can occur in load mode. When the mode changes from load to count, the counter will now latch the value currently in it, and start counting down from there. In the count mode, the current value of $4008 is ignored by the counter (but still retained in $4008). Described below is how the mode of the linear counter is set:

+


+


+

Writes to $400B

+

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

+

cur        mode

+

---        ----

+

1        load

+

0        load (on next linear counter clock), count

+


+

 Cur is the current state of the MSB of $4008.

+


+


+

Writes to $4008

+

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

+

old        new        mode

+

---        ---        ----

+

0        X        count

+

1        0        no change (during the CPU write cycle), count

+

1        1        no change

+


+

 Old and new represent the state(s) of the MSB of $4008. Old is the value being replaced in the MSB of $4008 on the write, and new is the value replacing the old one.

+


+

 "no change" indicates that the mode of the linear counter will not change from the last.

+


+

 Note that writes to $400B when $4008.7=0 only loads the linear counter with the value in $4008 on the next *linear* counter clock (and NOT at the end of the CPU write cycle). This is a correction from older versions of this doc.

+


+


+

+--------------------+

+

| Programmable timer |

+

+--------------------+

+

 The programmable timer is a 11-bit presettable down counter, and is found in the square, triangle, and noise channel(s). The bit assignments are as follows:

+


+

$4002(sq1)/$4006(sq2)/$400A(Tri) bits

+

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

+

0-7        represent bits 0-7 of the 11-bit wavelength

+


+

$4003(sq1)/$4007(sq2)/$400B(Tri) bits

+

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

+

0-2        represent bits 8-A of the 11-bit wavelength

+


+

 Note that on the noise channel, the 11 bits are not available directly. See the wavelength converter section, for more details.

+


+

 The counter has automatic syncronous reloading upon terminal count (count=0), therefore the counter will count for N+1 (N is the 11-bit loaded value) clock cycles before arriving at terminal count, and reloading. This counter will typically be clocked at the 2A03's internal 6502 speed (1.79 MHz), and produces an output frequency of 1.79 MHz/(N+1). The terminal count's output spike length is typically no longer than half a CPU clock. The TC signal will then be fed to the appropriate device for the particular sound channel (for square, this terminal count spike will lead to the duty cycle generator. For the triangle, the spike will be fed to the triangle step generator. For noise, this signal will go to the random number generator unit).

+


+


+

+----------------+

+

| Length counter |

+

+----------------+

+

 The length counter is found in all sound channels. It is essentially a 7-bit down counter, and is conditionally clocked at a frequency of 60 Hz.

+


+

 When the length counter arrives at a count of 0, the counter will be stopped (stay on 0), and the appropriate channel will be silenced.

+


+

 The length counter clock disable bit, found in all the channels, can also be used to halt the count sequence of the length counter for the appropriate channel, by writing a 1 out to it. A 0 condition will permit counting (unless of course, the counter's current count = 0). Location(s) of the length counter clock disable bit:

+


+

$4000(sq1)/$4004(sq2)/$400C(noise) bits

+

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

+

5        length counter clock disable

+


+

$4008(tri) bits

+

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

+

7        length counter clock disable

+


+

 To load the length counter with a specified count, a write must be made out to the length register. Location(s) of the length register:

+


+

$4003(sq1)/$4007(sq2)/$400B(tri)/$400F(noise) bits

+

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

+

3-7        length

+


+

 The 5-bit length value written, determines what 7-bit value the length counter will start counting from. A conversion table here will show how the values are translated.

+


+

       +-----------------------+

+

       |        bit3=0        |

+

       +-------+---------------+

+

       |        |frames                |

+

       |bits        +-------+-------+

+

       |4-6        |bit7=0        |bit7=1        |

+

       +-------+-------+-------+

+

       |0        |05        |06        |

+

       |1        |0A        |0C        |

+

       |2        |14        |18        |

+

       |3        |28        |30        |

+

       |4        |50        |60        |

+

       |5        |1E        |24        |

+

       |6        |07        |08        |

+

       |7        |0D        |10        |

+

       +-------+-------+-------+

+


+

       +---------------+

+

       |        bit3=1        |

+

       +-------+-------+

+

       |bits        |        |

+

       |4-7        |frames        |

+

       +-------+-------+

+

       |0        |7F        |

+

       |1        |01        |        

+

       |2        |02        |

+

       |3        |03        |

+

       |4        |04        |

+

       |5        |05        |

+

       |6        |06        |

+

       |7        |07        |

+

       |8        |08        |

+

       |9        |09        |

+

       |A        |0A        |

+

       |B        |0B        |

+

       |C        |0C        |

+

       |D        |0D        |

+

       |E        |0E        |

+

       |F        |0F        |

+

       +-------+-------+

+


+

 The length counter's real-time status for each channel can be attained. A 0 is returned for a zero count status in the length counter (channel's sound is disabled), and 1 for a non-zero status. Here's the bit description of the length counter status register:

+


+

$4015(read)

+

-----------

+

0        length counter status of square wave channel 1

+

1        length counter status of square wave channel 2

+

2        length counter status of triangle wave channel

+

3        length counter status of noise channel

+

4        length counter status of DMC (see "DMC.TXT" for details)

+

5        unknown

+

6        frame IRQ status

+

7        IRQ status of DMC (see "DMC.TXT" for details)

+


+

 Writing a 0 to the channel enable register will force the length counters to always contain a count equal to 0, which renders that specific channel disabled (as if it doesn't exist). Writing a 1 to the channel enable register disables the forced length counter value of 0, but will not change the count itself (it will still be whatever it was prior to the writing of 1).

+


+

 Bit description of the channel enable register:

+


+

$4015(write)

+

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

+

0        enable square wave channel 1

+

1        enable square wave channel 2

+

2        enable triangle wave channel

+

3        enable noise channel

+

4        enable DMC channel (see "DMC.TXT" for details)

+

5-7        unknown

+


+

 Note that all 5 used bits in this register will be set to 0 upon system reset.

+


+


+

+-----------+

+

| 4-bit DAC |

+

+-----------+

+

 This is just a standard 4-bit DAC with 16 steps of output voltage resolution, and is used by all 4 sound channels. On the 2A03, square wave 1 & 2 are mixed together, and are available via pin 1. Triangle & noise are available on pin 2.

+


+

 These analog outputs require a negative current source, to attain linear symmetry on the various output voltage levels generated by the channel(s) (moreover, to get the sound to be audible). Instead of current sources, the NES uses external 100 ohm pull-down resistors. This results in the output waveforms having some linear asymmetry (i.e., as the desired output voltage increases on a linear scale, the actual outputted voltage increases less and less each step).

+


+

 The side effect of this is that the DMC's 7-bit DAC port ($4011) is able to indirectly control the volume (somewhat) of both triangle & noise channels. While I have not measured the voltage asymmetery, others on the NESdev messageboards have posted their findings. The conclusion is that when $4011 is 0, triangle & noise volume outputs are at maximum. When $4011 = 7F, the triangle & noise channel outputs operate at only 57% total volume.

+


+

 The odd thing is that a few games actually take advantage of this "volume" feature, and write values to $4011 in order to regulate the amplitude of the triangle wave channel's output.

+


+


+

+------------------------------+

+

| Volume / envelope decay unit |

+

+------------------------------+

+

 The volume / envelope decay hardware is found only in the square wave and noise channels.

+


+

$4000(sq1)/$4004(sq2)/$400C(noise)

+

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

+

0-3        volume / envelope decay rate

+

4        envelope decay disable

+

5        envelope decay looping enable

+


+

 When the envelope decay disable bit (bit 4) is set (1), the current volume value (bits 0-3) is sent directly to the channel's DAC. However, depending on certain conditions, this 4-bit volume value will be ignored, and a value of 0 will be sent to the DAC instead. This means that while the channel is enabled (producing sound), the output of the channel (what you'll hear from the DAC) will either be the 4-bit volume value, or 0. This also means that a 4-bit volume value of 0 will result in no audible sound. These conditions are as follows:

+


+

 - When hardware in the channel wants to disable it's sound output (like the length counter, or sweep unit (square channels only)).

+


+

 - On the negative portion of the output frequency signal coming from the duty cycle / random number generator hardware (square wave channel / noise channel).

+


+

 When the envelope decay disable bit is cleared, bits 0-3 now control the envelope decay rate, and an internal 4-bit down counter (hereon the envelope decay counter) now controls the channel's volume level. "Envelope decay" is used to describe the action of the channel's audio output volume starting from a certain value, and decreasing by 1 at a fixed (linear) rate (which produces a "fade-out" sounding effect). This fixed decrement rate is controlled by the envelope decay rate (bits 0-3). The calculated decrement rate is 240Hz/(N+1), where N is any value between $0-$F.

+


+

 When the channel's envelope decay counter reaches a value of 0, depending on the status of the envelope decay looping enable bit (bit 5, which is shared with the length counter's clock disable bit), 2 different things will happen:

+


+

bit 5        action

+

-----        ------

+

0        The envelope decay count will stay at 0 (channel silenced).

+

1        The envelope decay count will wrap-around to $F (upon the next clock cycle). The envelope decay counter will then continue to count down normally.

+


+

 Only a write out to $4003/$4007/$400F will reset the current envelope decay counter to a known state (to $F, the maximum volume level) for the appropriate channel's envelope decay hardware. Otherwise, the envelope decay counter is always counting down (by 1) at the frequency currently contained in the volume / envelope decay rate bits (even when envelope decays are disabled (setting bit 4)), except when the envelope decay counter contains a value of 0, and envelope decay looping (bit 5) is disabled (0).

+


+


+

+------------+

+

| Sweep unit |

+

+------------+

+

 The sweep unit is only found in the square wave channels. The controls for the sweep unit have been mapped in at $4001 for square 1, and $4005 for square 2.

+


+

 The controls

+

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

+

 Bit 7           when this bit is set (1), sweeping is active. This results in real-time increasing or decreasing of the the current wavelength value (the audible frequency will decrease or increase, respectively). The wavelength value in $4002/3 ($4006/7) is constantly read & updated by the sweep. Modifying the contents of $4002/3 will be immediately audible, and will result in the sweep now starting from this new wavelength value.

+


+

 Bits 6-4        These 3 bits represent the sweep refresh rate, or the frequency at which $4002/3 is updated with the new calculated wavelength. The refresh rate frequency is 120Hz/(N+1), where N is the value written, between 0 and 7.

+


+

 Bit 3           This bit controls the sweep mode. When this bit is set (1), sweeps will decrease the current wavelength value, as a 0 will increase the current wavelength.

+


+

 Bits 2-0        These bits control the right shift amount of the new calculated sweep update wavelength. Code that shows how the sweep unit calculates a new sweep wavelength is as follows:

+

 

+

bit 3

+

-----

+

0        New = Wavelength + (Wavelength >> N)

+

1        New = Wavelength - (Wavelength >> N) (minus an additional 1, if using square wave channel 1)

+


+

 where N is the the shift right value, between 0-7.

+


+

 Note that in decrease mode, for subtracting the 2 values:

+

 1's compliment (NOT) is being used for square wave channel 1

+

 2's compliment (NEG) is being used for square wave channel 2

+


+

 This information is currently the only known difference between the 2 square wave channels.

+


+

 On each sweep refresh clock, the Wavelength register will be updated with the New value, but only if all 3 of these conditions are met:

+


+

 - bit 7 is set (sweeping enabled)

+

 - the shift value (which is N in the formula) does not equal to 0

+

 - the channel's length counter contains a non-zero value

+


+

 Notes

+

 -----

+

 There are certain conditions that will cause the sweep unit to silence the channel, and halt the sweep refresh clock (which effectively stops sweep action, if any). Note that these conditions pertain regardless of any sweep refresh rate values, or if sweeping is enabled/disabled (via bit 7).

+


+

 - an 11-bit wavelength value less than $008 will cause this condition

+

 - if the sweep unit is currently set to increase mode, the New calculated wavelength value will always be tested to see if a carry (bit $B) was generated or not (if sweeping is enabled, this carry will be examined before the Wavelength register is updated) from the shift addition calculation. If carry equals 1, the channel is silenced, and sweep action is halted.

+


+


+

+----------------------+

+

| Duty cycle generator |

+

+----------------------+

+

 The duty cycle generator takes the fequency produced from the 11-bit programmable timer, and uses a 4 bit counter to produce 4 types of duty cycles. The output frequency is then 1/16 that of the programmable timer. The duty cycle hardware is only found in the square wave channels. The bit assignments are as follows:

+


+

$4000(sq1)/$4004(sq2)

+

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

+

6-7        Duty cycle type

+


+

       duty (positive/negative)

+

val        in clock cycles

+

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

+

00         2/14

+

01         4/12

+

10         8/ 8

+

11        12/ 4

+


+

 Where val represents bits 6-7 of $4000/$4004.

+


+

 This counter is reset when the length counter of the same channel is written to (via $4003/$4007).

+


+

 The output frequency at this point will now be fed to the volume/envelope decay hardware.

+


+


+

+----------------------+

+

| Wavelength converter |

+

+----------------------+

+

 The wavelength converter is only used in the noise channel. It is used to convert a given 4-bit value to an 11-bit wavelength, which then is sent to the noise's own programmable timer. Here is the bit descriptions:

+


+

$400E bits

+

----------

+

0-3        The 4-bit value to be converted

+


+

 Below is a conversion chart that shows what 4-bit value will represent the 11-bit wavelength to be fed to the channel's programmable timer:

+


+

value        octave        scale        CPU clock cycles (11-bit wavelength+1)

+

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

+

0        15        A        002

+

1        14        A        004

+

2        13        A        008

+

3        12        A        010

+

4        11        A        020

+

5        11        D        030

+

6        10        A        040

+

7        10        F        050

+

8        10        C        065

+

9         9        A        07F

+

A         9        D        0BE

+

B         8        A        0FE

+

C         8        D        17D

+

D         7        A        1FC

+

E         6        A        3F9

+

F         5        A        7F2

+


+

 Octave and scale information is provided for the music enthusiast programmer who is more familiar with notes than clock cycles.

+


+


+

+-------------------------+

+

| Random number generator |

+

+-------------------------+

+

 The noise channel has a 1-bit pseudo-random number generator. It's based on a 15-bit shift register, and an exclusive or gate. The generator can produce two types of random number sequences: long, and short. The long sequence generates 32,767-bit long number patterns. The short sequence generates 93-bit long number patterns. The 93-bit mode will generally produce higher sounding playback frequencys on the channel. Here is the bit that controls the mode:

+


+

$400E bits

+

----------

+

7        mode

+


+

 If mode=0, then 32,767-bit long number sequences will be produced (32K mode), otherwise 93-bit long number sequences will be produced (93-bit mode).

+


+

 The following diagram shows where the XOR taps are taken off the shift register to produce the 1-bit pseudo-random number sequences for each mode.

+


+

mode            <-----

+

----        EDCBA9876543210

+

32K        **

+

93-bit        *     *

+


+

 The current result of the XOR will be transferred into bit position 0 of the SR, upon the next shift cycle. The 1-bit random number output is taken from pin E, is inverted, then is sent to the volume/envelope decay hardware for the noise channel. The shift register is shifted upon recieving 2 clock pulses from the programmable timer (the shift frequency will be half that of the frequency from the programmable timer (one octave lower)).

+


+

 On system reset, this shift register is loaded with a value of 1.

+


+


+

RP2A03E quirk

+

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

+

 I have been informed that revisions of the 2A03 before "F" actually lacked support for the 93-bit looped noise playback mode. While the Famicom's 2A03 went through 4 revisions (E..H), I think that only one was ever used for the front loading NES: "G". Other differences between 2A03 revisions are unknown.

+


+


+

EOF

+

+

Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NLFilesFormat.html b/web/help/NLFilesFormat.html index 86b0d837..e414b15d 100644 --- a/web/help/NLFilesFormat.html +++ b/web/help/NLFilesFormat.html @@ -1,117 +1,310 @@ - - + + + + + - .nl files format - - - - - - - - - - + + + + + + + + .nl files format + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

.nl files format

- - -
-
- Parent - - Previous - -
-
-
-
- -

-

.nl files format

-


-


-

FCEUX implements Symbolic Debugger which uses "NameList" files to store the data about labels and comments. The needed files are created automatically when user right-clicks an address in Disassembly and enters a symbolic name or a comment for it. The files are stored in the same folder as the debugged ROM, and they inherit the name of the ROM.

-

These files are simple ASCII text files. You can edit them in any text editor like Notepad.

-


-

When reverse-engineering a game for which you don't have a source, you can reconstruct the logic incrementally, by adding labels/comments while debugging (right-clicking addresses).

-


-

But if you want to debug your own homebrew game, you can setup your workflow to automatically export all names and comments when building the game using your favourite assembler (e.g. ca65 or ASM6). This way you can use FCEUX as a Source-Level Debugger.

-


-

Example: for the ROM called "NES Test Cart (PD).nes" the NL files will be named "NES Test Cart (PD).nes.0.nl", "NES Test Cart (PD).nes.ram.nl", etc.

-


-

Example of contents of a NL file:

-


-

$C000#NewName1#Comment1

-

$C002##Comment2

-

$C004#NewName2#

-

$C006#NewName3#MultilineComment-Part1

-

\MultilineComment-Part2

-

\MultilineComment-Part3

-

$C008/10#NewName4#

-


-

Every line contains two # characters which separate the three parts of one line:

-

* The first part (starting with a $ character) is the address to be renamed. Optionally you can add a "/number" part which marks the offsets as a beginning of an array of the given size (the size must be specified in hex form).

-

* The second (optional) part is the new name of that address. Whenever the line of that address is shown in the disassembly window, an extra line saying "NewName1: " is shown above it.  Instructions referencing this address, for example JSR $C000 are also changed to JSR NewName1 (in that example).

-

* The third (optional) part is the comment that's also added above the disassembly line the comment refers to. It works exactly like the additional name line, only the prefix of that line is different. Comment lines start with "; ".  Multi-lines comments are possible. Lines in an NL file starting with the \ character are just appended to the comment of the preceding line. Multi-line comments are also shown in multiple lines in the disassembly window.

-


-

In the example above, the first line contains all three parts. Using this NL file, all references to the address $C000 are replaced with NewName1, and whenever line $C000 is shown in the disassembly window (or Trace Logger window) an additional comment is also visible right above the actual disassembled line. The second example line defines only a comment while the third line defines only a name. Following that, there's a multi-line comment definition for address $C006. The last line defines an array called NewName4 of size 0x10 (= 16) bytes starting at offset $C008. FCEUX will regard the line like there are 16 lines describing 16 adjacent addresses with names like NewName4[0], NewName4[1], ... NewName4[F].

-


-

NL files must follow a specific naming convention to account for bank swapping. Each bank needs its own NL file with a hexadecimal number of the bank.

-

For instance, an NES file named "mygame.nes" that has 4 banks (i.e. ROM size = 64k) would have these NL files:

-


-

mygame.nes.ram.nl

-

mygame.nes.0.nl

-

mygame.nes.1.nl

-

mygame.nes.2.nl

-

mygame.nes.3.nl

-


-

All NL files must be in the same directory as the ROM file itself.

-


-

RAM can also be given its own NL file. In the *.ram.nl file you can name and comment RAM addresses (system bus range of 0x0000 - 0x7FFF) instead of ROM addresses. In this case, you might use a line such as:

-


-

$00A5#Mic Test OK#00=Not Passed, 01=Passed

-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured Kindle eBooks generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

.nl files format

+ +
+ +

+

.nl files format

+


+


+

FCEUX implements Symbolic Debugger which uses "NameList" files to store the data about labels and comments. The needed files are created automatically when user right-clicks an address in Disassembly and enters a symbolic name or a comment for it. The files are stored in the same folder as the debugged ROM, and they inherit the name of the ROM.

+

These files are simple ASCII text files. You can edit them in any text editor like Notepad.

+


+

When reverse-engineering a game for which you don't have a source, you can reconstruct the logic incrementally, by adding labels/comments while debugging (right-clicking addresses).

+


+

But if you want to debug your own homebrew game, you can setup your workflow to automatically export all names and comments when building the game using your favourite assembler (e.g. ca65 or ASM6). This way you can use FCEUX as a Source-Level Debugger.

+


+

Example: for the ROM called "NES Test Cart (PD).nes" the NL files will be named "NES Test Cart (PD).nes.0.nl", "NES Test Cart (PD).nes.ram.nl", etc. 

+


+

Example of contents of a NL file:

+


+

$C000#NewName1#Comment1

+

$C002##Comment2

+

$C004#NewName2#

+

$C006#NewName3#MultilineComment-Part1

+

\MultilineComment-Part2

+

\MultilineComment-Part3

+

$C008/10#NewName4#

+


+

Every line contains two # characters which separate the three parts of one line:

+

* The first part (starting with a $ character) is the address to be renamed. Optionally you can add a "/number" part which marks the offsets as a beginning of an array of the given size (the size must be specified in hex form).

+

* The second (optional) part is the new name of that address. Whenever the line of that address is shown in the disassembly window, an extra line saying "NewName1: " is shown above it.  Instructions referencing this address, for example JSR $C000 are also changed to JSR NewName1 (in that example).

+

* The third (optional) part is the comment that's also added above the disassembly line the comment refers to. It works exactly like the additional name line, only the prefix of that line is different. Comment lines start with "; ".  Multi-lines comments are possible. Lines in an NL file starting with the \ character are just appended to the comment of the preceding line. Multi-line comments are also shown in multiple lines in the disassembly window.

+


+

In the example above, the first line contains all three parts. Using this NL file, all references to the address $C000 are replaced with NewName1, and whenever line $C000 is shown in the disassembly window (or Trace Logger window) an additional comment is also visible right above the actual disassembled line. The second example line defines only a comment while the third line defines only a name. Following that, there's a multi-line comment definition for address $C006. The last line defines an array called NewName4 of size 0x10 (= 16) bytes starting at offset $C008. FCEUX will regard the line like there are 16 lines describing 16 adjacent addresses with names like NewName4[0], NewName4[1], ... NewName4[F].

+


+

NL files must follow a specific naming convention to account for bank swapping. Each bank needs its own NL file with a hexadecimal number of the bank.

+

For instance, an NES file named "mygame.nes" that has 4 banks (i.e. ROM size = 64k) would have these NL files:

+


+

mygame.nes.ram.nl

+

mygame.nes.0.nl

+

mygame.nes.1.nl

+

mygame.nes.2.nl

+

mygame.nes.3.nl

+


+

All NL files must be in the same directory as the ROM file itself.

+


+

RAM can also be given its own NL file. In the *.ram.nl file you can name and comment RAM addresses (system bus range of 0x0000 - 0x7FFF) instead of ROM addresses. In this case, you might use a line such as:

+


+

$00A5#Mic Test OK#00=Not Passed, 01=Passed

+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create CHM Help documents

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NSFFormat.html b/web/help/NSFFormat.html index 0f2e5f8c..86f50b5f 100644 --- a/web/help/NSFFormat.html +++ b/web/help/NSFFormat.html @@ -1,408 +1,599 @@ - - + + + + + - NSF Format - - - - - - - - - - + + + + + + + + NSF Format + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

NSF Format

- -
- Technical Information ›› Sound ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

NES Music Format Spec

-

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

-


-


-

By: Kevin Horton  khorton@iquest.net

-


-


-

NOTE:

-

-----

-


-


-

Remember that I am very willing to add stuff and update this spec.  If

-

you find a new sound chip or other change let me know and I will get back

-

with you.  E-mail to the above address.

-


-


-

V1.61 - 06/27/2000 Updated spec a bit

-

V1.60 - 06/01/2000 Updated Sunsoft, MMC5, and Namco chip information

-

V1.50 - 05/28/2000 Updated FDS, added Sunsoft and Namco chips

-

V1.32 - 11/27/1999 Added MMC5 register locations

-

V1.30 - 11/14/1999 Added MMC5 audio bit, added some register info

-

V1.20 - 09/12/1999 VRC and FDS prelim sound info added

-

V1.00 - 05/11/1999 First official NSF specification file

-


-


-


-

This file encompasses a way to transfer NES music data in a small, easy to

-

use format.

-


-

The basic idea is one rips the music/sound code from an NES game and prepends

-

a small header to the data.

-


-

A program of some form (6502/sound emulator) then takes the data and loads

-

it into the proper place into the 6502's address space, then inits and plays

-

the tune.

-


-

Here's an overview of the header:

-


-

offset  # of bytes   Function

-

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

-


-

0000    5   STRING  "NESM",01Ah  ; denotes an NES sound format file

-

0005    1   BYTE    Version number (currently 01h)

-

0006    1   BYTE    Total songs   (1=1 song, 2=2 songs, etc)

-

0007    1   BYTE    Starting song (1= 1st song, 2=2nd song, etc)

-

0008    2   WORD    (lo/hi) load address of data (8000-FFFF)

-

000a    2   WORD    (lo/hi) init address of data (8000-FFFF)

-

000c    2   WORD    (lo/hi) play address of data (8000-FFFF)

-

000e    32  STRING  The name of the song, null terminated

-

002e    32  STRING  The artist, if known, null terminated

-

004e    32  STRING  The Copyright holder, null terminated

-

006e    2   WORD    (lo/hi) speed, in 1/1000000th sec ticks, NTSC (see text)

-

0070    8   BYTE    Bankswitch Init Values (see text, and FDS section)

-

0078    2   WORD    (lo/hi) speed, in 1/1000000th sec ticks, PAL (see text)

-

007a    1   BYTE    PAL/NTSC bits:

-

                bit 0: if clear, this is an NTSC tune

-

                bit 0: if set, this is a PAL tune

-

                bit 1: if set, this is a dual PAL/NTSC tune

-

                bits 2-7: not used. they *must* be 0

-

007b    1   BYTE    Extra Sound Chip Support

-

                bit 0: if set, this song uses VRCVI

-

                bit 1: if set, this song uses VRCVII

-

                bit 2: if set, this song uses FDS Sound

-

                bit 3: if set, this song uses MMC5 audio

-

                bit 4: if set, this song uses Namco 106

-

                bit 5: if set, this song uses Sunsoft FME-07

-

                bits 6,7: future expansion: they *must* be 0

-

007c    4   ----    4 extra bytes for expansion (must be 00h)

-

0080    nnn ----    The music program/data follows

-


-

This may look somewhat familiar;  if so that's because this is somewhat

-

sorta of based on the PSID file format for C64 music/sound.

-


-


-

Loading a tune into RAM

-

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

-


-

If offsets 0070h to 0077h have 00h in them, then bankswitching is *not*

-

used.  If one or more bytes are something other than 00h then bankswitching

-

is used.  If bankswitching is used then the load address is still used,

-

but you now use (ADDRESS AND 0FFFh) to determine where on the first bank

-

to load the data.

-


-


-

Each bank is 4K in size, and that means there are 8 of them for the

-

entire 08000h-0ffffh range in the 6502's address space.  You determine where

-

in memory the data goes by setting bytes 070h thru 077h in the file.

-

These determine the inital bank values that will be used, and hence where

-

the data will be loaded into the address space.

-


-

Here's an example:

-


-

METROID.NSF will be used for the following explaination.

-


-

The file is set up like so:  (starting at 070h in the file)

-


-


-

0070: 05 05 05 05 05 05 05 05 - 00 00 00 00 00 00 00 00

-

0080: ... music data goes here...

-


-

Since 0070h-0077h are something other than 00h, then we know that this

-

tune uses bankswitching.  The load address for the data is specified as

-

08000h.  We take this AND 0fffh and get 0000h, so we will load data in

-

at byte 0 of bank 0, since data is loaded into the banks sequentially

-

starting from bank 0 up until the music data is fully loaded.

-


-

Metroid has 6 4K banks in it, numbered 0 through 5.  The 6502's address

-

space has 8 4K bankswitchable blocks on it, starting at 08000h-08fffh,

-

09000h-09fffh, 0a000h-0afffh ... 0f000h-0ffffh.  Each one of these is 4K in

-

size, and the current bank is controlled by writes to 05ff8h thru 05fffh,

-

one byte per bank.  So, 05ff8h controls the 08000h-08fffh range, 05ff9h

-

controls the 09000h-09fffh range, etc. up to 05fffh which controls the

-

0f000h-0ffffh range.  When the song is loaded into RAM, it is loaded into

-

the banks and not the 6502's address space.  Once this is done, then the

-

bank control registers are written to set up the inital bank values.

-

To do this, the value at 0070h in the file is written to 05ff8h, 0071h

-

is written to 05ff9h, etc. all the way to 0077h is written to 05fffh.

-

This is should be done before every call to the init routine.

-


-

If the tune was not bankswitched, then it is simply loaded in at the

-

specified load address, until EOF

-


-


-

Initalizing a tune

-

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

-


-

This is pretty simple.  Load the desired song # into the accumulator,

-

minus 1 and set the X register to specify PAL (X=1) or NTSC (X=0).

-

If this is a single standard tune (i.e. PAL *or* NTSC but not both)

-

then the X register contents should not matter.  Once the song # and

-

optional PAL/NTSC standard are loaded, simply call the INIT address.

-

Once init is done, it should perform an RTS.

-


-


-

Playing a tune

-

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

-


-

Once the tune has been initalized, it can now be played.  To do this,

-

simply call the play address several times a second.  How many times

-

per second is determined by offsets 006eh and 006fh in the file.

-

These bytes denote the speed of playback in 1/1000000ths of a second.  

-

For the "usual" 60Hz playback rate, set this to 411ah.  

-


-

To generate a differing playback rate, use this formula:

-


-


-

        1000000

-

PBRATE= ---------

-

         speed

-


-

Where PBRATE is the value you stick into 006e/006fh in the file, and

-

speed is the desired speed in hertz.

-


-


-

"Proper" way to load the tune

-

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

-


-

1) If the tune is bankswitched, go to #3.

-


-

2) Load the data into the 6502's address space starting at the specified

-

  load address. Go to #4.

-


-

3) Load the data into a RAM area, starting at (start_address AND 0fffh).

-


-

4) Tune load is done.

-


-


-

"Proper" way to init a tune

-

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

-


-

1) Clear all RAM at 0000h-07ffh.

-


-

2) Clear all RAM at 6000h-7fffh.

-


-

3) Init the sound registers by writing 00h to 04000-0400Fh, 10h to 4010h,

-

  and 00h to 4011h-4013h.

-


-

4) Set volume register 04015h to 00fh.

-


-

5) If this is a banked tune, load the bank values from the header into

-

  5ff8-5fffh.

-


-

6) Set the accumulator and X registers for the desired song.

-


-

7) Call the music init routine.

-


-


-

"Proper" way to play a tune

-

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

-


-

1) Call the play address of the music at periodic intervals determined

-

  by the speed words.  Which word to use is determined by which mode

-

  you are in- PAL or NTSC.

-


-


-

Sound Chip Support

-

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

-


-

Byte 007bh of the file stores the sound chip flags.  If a particular flag

-

is set, those sound registers should be enabled.  If the flag is clear,

-

then those registers should be disabled.

-


-

* VRCVI Uses registers 9000-9002, A000-A002, and B000-B002, write only.

-


-

Caveats: 1) The above registers are *write only* and must not disrupt music

-

           code that happens to be stored there.

-


-

        2) Major caveat:  The A0 and A1 lines are flipped on a few games!!

-

           If you rip the music and it sounds all funny, flip around

-

           the xxx1 and xxx2 register pairs.  (i.e. 9001 and 9002)  9000

-

           and 9003 can be left untouched.  I decided to do this since it

-

           would make things easier all around, and this means you only

-

           will have to change the music code in a very few places (6).

-

           Esper2 and Madara will need this change, while Castlevania 3j

-

           will not for instance.

-

       

-

        3) See my VRCVI.TXT doc for a complete register description.

-


-

* VRCVII Uses registers 9010 and 9030, write only.

-


-

Caveats: 1) Same caveat as #1, above.

-


-

        2) See my VRCVII.TXT doc for a complete register description.

-


-

* FDS Sound uses registers from 4040 through 4092.

-


-

Caveats: 1) 6000-DFFF is assumed to be RAM, since 6000-DFFF is RAM on the

-

           FDS.  E000-FFFF is usually not included in FDS games because

-

           it is the BIOS ROM.  However, it can be used on FDS rips to help

-

           the ripper (for modified play/init addresses).

-


-

        2) Bankswitching operates slightly different on FDS tunes.  

-

           5FF6 and 5FF7 control the banks 6000-6FFF and 7000-7FFF

-

           respectively.  NSF header offsets 76h and 77h correspond to

-

           *both* 6000-7FFF *AND* E000-FFFF.  Keep this in mind!

-


-

* MMC5 Sound Uses registers 5000-5015, write only as well as 5205 and 5206,

-

           and 5C00-5FF5

-


-

Caveats: 1) Generating a proper doc file.  Be patient.  

-


-

        2) 5205 and 5206 are a hardware 8*8 multiplier.  The idea being

-

           you write your two bytes to be multiplied into 5205 and 5206

-

           and after doing so, you read the result back out.  Still working

-

           on what exactly triggers it (I think a write to either 5205

-

           or 5206 triggers the multiply).

-


-

        3) 5C00-5FF5 should be RAM to emulate EXRAM while in MMC5 mode.

-


-

Note: Thanks to Mamiya for the EXRAM info.

-


-


-

* Namco 106 Sound Uses registers 4800 and F800.  

-


-

           This works similar to VRC7.  4800 is the "data" port which is

-

           readable and writable, while F800 is the "address" port and is

-

           writable only.

-


-

           The address is 7 bits plus a "mode" bit.  Bit 7 controls

-

           address auto-incrementing.  If bit 7 is set, the address will

-

           auto-increment after a byte of data is read or written from/to

-

           4800.

-


-

           $40 ffffffff f:frequency L

-

           $42 ffffffff f:frequency M

-

           $44 ---sssff f:frequency H s:tone length (8-s)*4 in 4bit-samples

-

           $46 tttttttt t:tone address(4bit-address,$41 means high-4bits of $20)

-

           $47 -cccvvvv v:linear volume 1+c:number of channels in use($7F only)

-

           $40-47:ch1 $48-4F:ch2 ... $78-7F:ch8

-

           ch2-ch8 same to ch1

-


-

           $00-3F(8ch)...77(1ch) hhhhllll tone data

-

           h:odd address data(signed 4bit)

-

           l:even address data(signed 4bit)

-


-

           real frequency = (f * NES_BASECYCLES) / (40000h * (c+1) * (8-s)*4 * 45)

-

           NES_BASECYCLES 21477270(Hz)

-


-

Note:  Very Special thanks to Mamiya for this information!

-


-


-

* Sunsoft FME-07 Sound uses registers C000 and E000

-


-

           This is similar to the common AY 3-8910 sound chip that is

-

           used on tons of arcade machines, and in the Intellivision.

-


-

           C000 is the address port

-

           E000 is the data port

-


-

           Both are write-only, and behave like the AY 3-8910.

-


-

Note:  Special thanks to Mamiya for this information as well

-


-


-

Caveats

-

-------

-


-

1) The starting song number and maximum song numbers start counting at

-

  1, while the init address of the tune starts counting at 0.  To

-

  "fix", simply pass the desired song number minus 1 to the init

-

  routine.

-


-

2) The NTSC speed word is used *only* for NTSC tunes, or dual PAL/NTSC tunes.

-

  The PAL speed word is used *only* for PAL tunes, or dual PAL/NTSC tunes.

-


-

3) The length of the text in the name, artist, and copyright fields must

-

  be 31 characters or less!  There has to be at least a single NULL byte

-

  (00h) after the text, between fields.

-


-

4) If a field is not known (name, artist, copyright) then the field must

-

  contain the string "<?>" (without quotes).  

-


-

5) There should be 8K of RAM present at 6000-7FFFh. MMC5 tunes need RAM at

-

  5C00-5FF7 to emulate its EXRAM. 8000-FFFF Should be read-only (not

-

  writable) after a tune has loaded.  The only time this area should be

-

  writable is if an FDS tune is being played.

-


-

6) Do not assume the state of *anything* on entry to the init routine

-

  except A and X.  Y can be anything, as can the flags.  

-


-

7) Do not assume the state of *anything* on entry to the play routine either.

-

  Flags, X, A, and Y could be at any state.  I've fixed about 10 tunes

-

  because of this problem and the problem, above.

-


-

8) The stack sits at 1FFh and grows down.  Make sure the tune does not

-

  attempt to use 1F0h-1FFh for variables. (Armed Dragon Villigust did and

-

  I had to relocate its RAM usage to 2xx)

-


-

9) Variables should sit in the 0000h-07FFh area *only*.  If the tune writes

-

  outside this range, say 1400h this is bad and should be relocated.

-

  (Terminator 3 did this and I relocated it to 04xx).

-


-

That's it!

-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free iPhone documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

NSF Format

+ +
+ +

+

NES Music Format Spec

+

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

+


+


+

By: Kevin Horton  khorton@iquest.net

+


+


+

NOTE:

+

-----

+


+


+

Remember that I am very willing to add stuff and update this spec.  If

+

you find a new sound chip or other change let me know and I will get back

+

with you.  E-mail to the above address. 

+


+


+

V1.61 - 06/27/2000 Updated spec a bit

+

V1.60 - 06/01/2000 Updated Sunsoft, MMC5, and Namco chip information

+

V1.50 - 05/28/2000 Updated FDS, added Sunsoft and Namco chips

+

V1.32 - 11/27/1999 Added MMC5 register locations

+

V1.30 - 11/14/1999 Added MMC5 audio bit, added some register info

+

V1.20 - 09/12/1999 VRC and FDS prelim sound info added

+

V1.00 - 05/11/1999 First official NSF specification file

+


+


+


+

This file encompasses a way to transfer NES music data in a small, easy to

+

use format.

+


+

The basic idea is one rips the music/sound code from an NES game and prepends

+

a small header to the data.

+


+

A program of some form (6502/sound emulator) then takes the data and loads

+

it into the proper place into the 6502's address space, then inits and plays

+

the tune.

+


+

Here's an overview of the header:

+


+

offset  # of bytes   Function

+

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

+


+

0000    5   STRING  "NESM",01Ah  ; denotes an NES sound format file

+

0005    1   BYTE    Version number (currently 01h)

+

0006    1   BYTE    Total songs   (1=1 song, 2=2 songs, etc)

+

0007    1   BYTE    Starting song (1= 1st song, 2=2nd song, etc)

+

0008    2   WORD    (lo/hi) load address of data (8000-FFFF)

+

000a    2   WORD    (lo/hi) init address of data (8000-FFFF)

+

000c    2   WORD    (lo/hi) play address of data (8000-FFFF)

+

000e    32  STRING  The name of the song, null terminated

+

002e    32  STRING  The artist, if known, null terminated

+

004e    32  STRING  The Copyright holder, null terminated

+

006e    2   WORD    (lo/hi) speed, in 1/1000000th sec ticks, NTSC (see text)

+

0070    8   BYTE    Bankswitch Init Values (see text, and FDS section)

+

0078    2   WORD    (lo/hi) speed, in 1/1000000th sec ticks, PAL (see text)

+

007a    1   BYTE    PAL/NTSC bits:

+

                 bit 0: if clear, this is an NTSC tune

+

                 bit 0: if set, this is a PAL tune

+

                 bit 1: if set, this is a dual PAL/NTSC tune

+

                 bits 2-7: not used. they *must* be 0

+

007b    1   BYTE    Extra Sound Chip Support

+

                 bit 0: if set, this song uses VRCVI

+

                 bit 1: if set, this song uses VRCVII

+

                 bit 2: if set, this song uses FDS Sound

+

                 bit 3: if set, this song uses MMC5 audio

+

                 bit 4: if set, this song uses Namco 106

+

                 bit 5: if set, this song uses Sunsoft FME-07

+

                 bits 6,7: future expansion: they *must* be 0

+

007c    4   ----    4 extra bytes for expansion (must be 00h)

+

0080    nnn ----    The music program/data follows

+


+

This may look somewhat familiar;  if so that's because this is somewhat

+

sorta of based on the PSID file format for C64 music/sound.

+


+


+

Loading a tune into RAM

+

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

+


+

If offsets 0070h to 0077h have 00h in them, then bankswitching is *not*

+

used.  If one or more bytes are something other than 00h then bankswitching

+

is used.  If bankswitching is used then the load address is still used,

+

but you now use (ADDRESS AND 0FFFh) to determine where on the first bank

+

to load the data.

+


+


+

Each bank is 4K in size, and that means there are 8 of them for the

+

entire 08000h-0ffffh range in the 6502's address space.  You determine where

+

in memory the data goes by setting bytes 070h thru 077h in the file.

+

These determine the inital bank values that will be used, and hence where

+

the data will be loaded into the address space.

+


+

Here's an example:

+


+

METROID.NSF will be used for the following explaination.

+


+

The file is set up like so:  (starting at 070h in the file)

+


+


+

0070: 05 05 05 05 05 05 05 05 - 00 00 00 00 00 00 00 00

+

0080: ... music data goes here...

+


+

Since 0070h-0077h are something other than 00h, then we know that this

+

tune uses bankswitching.  The load address for the data is specified as

+

08000h.  We take this AND 0fffh and get 0000h, so we will load data in

+

at byte 0 of bank 0, since data is loaded into the banks sequentially

+

starting from bank 0 up until the music data is fully loaded.

+


+

Metroid has 6 4K banks in it, numbered 0 through 5.  The 6502's address

+

space has 8 4K bankswitchable blocks on it, starting at 08000h-08fffh,

+

09000h-09fffh, 0a000h-0afffh ... 0f000h-0ffffh.  Each one of these is 4K in

+

size, and the current bank is controlled by writes to 05ff8h thru 05fffh,

+

one byte per bank.  So, 05ff8h controls the 08000h-08fffh range, 05ff9h 

+

controls the 09000h-09fffh range, etc. up to 05fffh which controls the 

+

0f000h-0ffffh range.  When the song is loaded into RAM, it is loaded into

+

the banks and not the 6502's address space.  Once this is done, then the

+

bank control registers are written to set up the inital bank values.

+

To do this, the value at 0070h in the file is written to 05ff8h, 0071h

+

is written to 05ff9h, etc. all the way to 0077h is written to 05fffh.

+

This is should be done before every call to the init routine.

+


+

If the tune was not bankswitched, then it is simply loaded in at the 

+

specified load address, until EOF

+


+


+

Initalizing a tune

+

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

+


+

This is pretty simple.  Load the desired song # into the accumulator,

+

minus 1 and set the X register to specify PAL (X=1) or NTSC (X=0).

+

If this is a single standard tune (i.e. PAL *or* NTSC but not both)

+

then the X register contents should not matter.  Once the song # and

+

optional PAL/NTSC standard are loaded, simply call the INIT address.

+

Once init is done, it should perform an RTS.

+


+


+

Playing a tune

+

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

+


+

Once the tune has been initalized, it can now be played.  To do this,

+

simply call the play address several times a second.  How many times

+

per second is determined by offsets 006eh and 006fh in the file.

+

These bytes denote the speed of playback in 1/1000000ths of a second.  

+

For the "usual" 60Hz playback rate, set this to 411ah.  

+


+

To generate a differing playback rate, use this formula:

+


+


+

         1000000

+

PBRATE= ---------

+

          speed

+


+

Where PBRATE is the value you stick into 006e/006fh in the file, and

+

speed is the desired speed in hertz. 

+


+


+

"Proper" way to load the tune

+

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

+


+

1) If the tune is bankswitched, go to #3.

+


+

2) Load the data into the 6502's address space starting at the specified

+

   load address. Go to #4.

+


+

3) Load the data into a RAM area, starting at (start_address AND 0fffh).

+


+

4) Tune load is done.

+


+


+

"Proper" way to init a tune

+

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

+


+

1) Clear all RAM at 0000h-07ffh.

+


+

2) Clear all RAM at 6000h-7fffh.

+


+

3) Init the sound registers by writing 00h to 04000-0400Fh, 10h to 4010h,

+

   and 00h to 4011h-4013h.

+


+

4) Set volume register 04015h to 00fh.

+


+

5) If this is a banked tune, load the bank values from the header into

+

   5ff8-5fffh.

+


+

6) Set the accumulator and X registers for the desired song.

+


+

7) Call the music init routine.

+


+


+

"Proper" way to play a tune

+

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

+


+

1) Call the play address of the music at periodic intervals determined

+

   by the speed words.  Which word to use is determined by which mode

+

   you are in- PAL or NTSC.

+


+


+

Sound Chip Support

+

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

+


+

Byte 007bh of the file stores the sound chip flags.  If a particular flag

+

is set, those sound registers should be enabled.  If the flag is clear,

+

then those registers should be disabled.

+


+

* VRCVI Uses registers 9000-9002, A000-A002, and B000-B002, write only.

+


+

Caveats: 1) The above registers are *write only* and must not disrupt music

+

            code that happens to be stored there.

+


+

         2) Major caveat:  The A0 and A1 lines are flipped on a few games!!

+

            If you rip the music and it sounds all funny, flip around 

+

            the xxx1 and xxx2 register pairs.  (i.e. 9001 and 9002)  9000

+

            and 9003 can be left untouched.  I decided to do this since it 

+

            would make things easier all around, and this means you only 

+

            will have to change the music code in a very few places (6).

+

            Esper2 and Madara will need this change, while Castlevania 3j

+

            will not for instance.

+

         

+

         3) See my VRCVI.TXT doc for a complete register description.

+


+

* VRCVII Uses registers 9010 and 9030, write only.

+


+

Caveats: 1) Same caveat as #1, above.

+


+

         2) See my VRCVII.TXT doc for a complete register description.

+


+

* FDS Sound uses registers from 4040 through 4092.

+


+

Caveats: 1) 6000-DFFF is assumed to be RAM, since 6000-DFFF is RAM on the

+

            FDS.  E000-FFFF is usually not included in FDS games because

+

            it is the BIOS ROM.  However, it can be used on FDS rips to help

+

            the ripper (for modified play/init addresses).

+


+

         2) Bankswitching operates slightly different on FDS tunes.  

+

            5FF6 and 5FF7 control the banks 6000-6FFF and 7000-7FFF 

+

            respectively.  NSF header offsets 76h and 77h correspond to

+

            *both* 6000-7FFF *AND* E000-FFFF.  Keep this in mind!

+


+

* MMC5 Sound Uses registers 5000-5015, write only as well as 5205 and 5206,

+

            and 5C00-5FF5

+


+

Caveats: 1) Generating a proper doc file.  Be patient.  

+


+

         2) 5205 and 5206 are a hardware 8*8 multiplier.  The idea being

+

            you write your two bytes to be multiplied into 5205 and 5206

+

            and after doing so, you read the result back out.  Still working

+

            on what exactly triggers it (I think a write to either 5205

+

            or 5206 triggers the multiply).

+


+

         3) 5C00-5FF5 should be RAM to emulate EXRAM while in MMC5 mode.

+


+

Note: Thanks to Mamiya for the EXRAM info.

+


+


+

* Namco 106 Sound Uses registers 4800 and F800.  

+


+

            This works similar to VRC7.  4800 is the "data" port which is

+

            readable and writable, while F800 is the "address" port and is

+

            writable only.

+


+

            The address is 7 bits plus a "mode" bit.  Bit 7 controls

+

            address auto-incrementing.  If bit 7 is set, the address will

+

            auto-increment after a byte of data is read or written from/to

+

            4800.

+


+

            $40 ffffffff f:frequency L

+

            $42 ffffffff f:frequency M

+

            $44 ---sssff f:frequency H s:tone length (8-s)*4 in 4bit-samples

+

            $46 tttttttt t:tone address(4bit-address,$41 means high-4bits of $20)

+

            $47 -cccvvvv v:linear volume 1+c:number of channels in use($7F only)

+

            $40-47:ch1 $48-4F:ch2 ... $78-7F:ch8

+

            ch2-ch8 same to ch1

+


+

            $00-3F(8ch)...77(1ch) hhhhllll tone data

+

            h:odd address data(signed 4bit)

+

            l:even address data(signed 4bit)

+


+

            real frequency = (f * NES_BASECYCLES) / (40000h * (c+1) * (8-s)*4 * 45)

+

            NES_BASECYCLES 21477270(Hz)

+


+

Note:  Very Special thanks to Mamiya for this information!

+


+


+

* Sunsoft FME-07 Sound uses registers C000 and E000

+


+

            This is similar to the common AY 3-8910 sound chip that is

+

            used on tons of arcade machines, and in the Intellivision.

+


+

            C000 is the address port

+

            E000 is the data port

+


+

            Both are write-only, and behave like the AY 3-8910.

+


+

Note:  Special thanks to Mamiya for this information as well

+


+


+

Caveats

+

-------

+


+

1) The starting song number and maximum song numbers start counting at

+

   1, while the init address of the tune starts counting at 0.  To

+

   "fix", simply pass the desired song number minus 1 to the init

+

   routine.

+


+

2) The NTSC speed word is used *only* for NTSC tunes, or dual PAL/NTSC tunes.

+

   The PAL speed word is used *only* for PAL tunes, or dual PAL/NTSC tunes.

+


+

3) The length of the text in the name, artist, and copyright fields must 

+

   be 31 characters or less!  There has to be at least a single NULL byte

+

   (00h) after the text, between fields.

+


+

4) If a field is not known (name, artist, copyright) then the field must

+

   contain the string "<?>" (without quotes).  

+


+

5) There should be 8K of RAM present at 6000-7FFFh. MMC5 tunes need RAM at

+

   5C00-5FF7 to emulate its EXRAM. 8000-FFFF Should be read-only (not 

+

   writable) after a tune has loaded.  The only time this area should be 

+

   writable is if an FDS tune is being played.

+


+

6) Do not assume the state of *anything* on entry to the init routine

+

   except A and X.  Y can be anything, as can the flags.  

+


+

7) Do not assume the state of *anything* on entry to the play routine either.

+

   Flags, X, A, and Y could be at any state.  I've fixed about 10 tunes

+

   because of this problem and the problem, above.

+


+

8) The stack sits at 1FFh and grows down.  Make sure the tune does not

+

   attempt to use 1F0h-1FFh for variables. (Armed Dragon Villigust did and

+

   I had to relocate its RAM usage to 2xx)

+


+

9) Variables should sit in the 0000h-07FFh area *only*.  If the tune writes

+

   outside this range, say 1400h this is bad and should be relocated. 

+

   (Terminator 3 did this and I relocated it to 04xx).

+


+

That's it!

+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured Help generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NameTableViewer.html b/web/help/NameTableViewer.html index 77903cd8..93cc2af7 100644 --- a/web/help/NameTableViewer.html +++ b/web/help/NameTableViewer.html @@ -1,96 +1,287 @@ - - + + + + + - Name Table Viewer - - - - - - - - - - + + + + + + + + Name Table Viewer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Name Table Viewer

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Name Table Viewer

-


-

Introduction

-


-

This displays the name tables as they exist in PPU memory. Furthermore, it shows you the game's current mirroring, and the current state of the PPU's scroll registers (if the option for this is set).  It also lets you change the mirroring on the fly (which will break most games).

-


-


-

Using the Name Table Viewer

-


-

Note that the Name Table Viewer will display the name tables using whatever CHR is present at the time the "Display on Scanline" scanline is reached. So for example if it does not correctly display a game's status bar, try setting it to update on a scanline in which the status bar is displayed.

-


-

The same applies to the Scroll Lines: they display the state of the PPU scroll registers when the "Display on Scanline" scanline is reached. So for example if said scanline is within the game's status bar, it will not display level scrolling because the horizontal scroll is always zero at the time that scanline is drawn. To display the level scrolling, set it to update on a scanline in which the level is displayed.

-


-

Display on scanline

-

This will show what it looks like when the NES has finished drawing that many scanlines to screen including any PPU data scroll line movement

-


-

Getting Tile Addresses

-

Placing the mouse cursor over the name table image will display the tile address of a given tile.

-


-


-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Name Table Viewer

+ +
+ +

+

Name Table Viewer

+


+

Introduction

+


+

This displays the name tables as they exist in PPU memory. Furthermore, it shows you the game's current mirroring, and the current state of the PPU's scroll registers (if the option for this is set).  It also lets you change the mirroring on the fly (which will break most games).

+


+


+

Using the Name Table Viewer

+


+

Note that the Name Table Viewer will display the name tables using whatever CHR is present at the time the "Display on Scanline" scanline is reached. So for example if it does not correctly display a game's status bar, try setting it to update on a scanline in which the status bar is displayed.

+


+

The same applies to the Scroll Lines: they display the state of the PPU scroll registers when the "Display on Scanline" scanline is reached. So for example if said scanline is within the game's status bar, it will not display level scrolling because the horizontal scroll is always zero at the time that scanline is drawn. To display the level scrolling, set it to update on a scanline in which the level is displayed.

+


+

Display on scanline

+

This will show what it looks like when the NES has finished drawing that many scanlines to screen including any PPU data scroll line movement

+


+

Getting Tile Addresses

+

Placing the mouse cursor over the name table image will display the tile address of a given tile.

+


+


+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easy EBook and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/NetworkPlay.html b/web/help/NetworkPlay.html index 02dce064..57165ae6 100644 --- a/web/help/NetworkPlay.html +++ b/web/help/NetworkPlay.html @@ -1,78 +1,269 @@ - - + + + + + - Network Play - - - - - - - - - - + + + + + + + + Network Play + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Network Play

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Network Play

-


-

Allows you to play against a human opponent over the internet.  Requires the use of FCEU server.

-


-

Currently however, FCEU Server runs very poorly and is hardly useable.  This issue will be resolved in a future release.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create CHM Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Network Play

+ +
+ +

+

Network Play

+


+

Allows you to play against a human opponent over the internet.  Requires the use of FCEU server.

+


+

Currently however, FCEU Server runs very poorly and is hardly useable.  This issue will be resolved in a future release.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Free help authoring tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Newtopic.html b/web/help/Newtopic.html new file mode 100644 index 00000000..4fb09d8f --- /dev/null +++ b/web/help/Newtopic.html @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + What's New? 2.3.0 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.3.0 (changelog)

+ +
+ +

+

What's New? 2.3.0

+

Released -- 15 December 2020

+


+


+

The 2.3.0 release includes 4 years worth of improvements and bug fixes.

+


+

Common

+
    +
  • 64 bit build support
  • +
+


+

Emulation

+
    +
  • Added Mapper 111 cheapocabra
  • +
  • Added Mapper 190
  • +
  • Added RAM Init Options: default (00 00 00 00 FF FF FF FF as always), all FF, all 00, random.
  • +
  • New UNIF mappers
  • +
+


+

Lua

+
    +
  • Various improvements and bug fixes to pre-existing functions
  • +
  • Fix parsing of lua colors over 0x80000000 on 32bits systems
  • +
  • Lua write callbacks: adding optional third parameter to retrieve the value written, added Sprites.lua script to visualize sprites
  • +
+


+

New Lua functions:

+
    +
  • emu.exit()
  • +
  • rom.getfilename()
  • +
+


+

Win32

+
    +
  • Various GUI improvements and bug fixes
  • +
+


+

Debugger

+
    +
  • Added memory read/write conditional breakpoint capability.
  • +
  • Added illegal opcode support for breakpoints.
  • +
  • Support for 'S' register in conditional debugger breakpoints
  • +
+


+

Trace Logger

+
    +
  • Added bank number log option
  • +
+


+

CDLogger

+
    +
  • Fix Fixed VRAM data logging glitch
  • +
+


+

Hex Editor

+
    +
  • Added OAM view feature
  • +
  • Bookmark fixes for all view region types
  • +
  • Prevent middle mouse button from attempting to "FreezeRam" when not in RAM mode
  • +
+


+

SDL

+
    +
  • GUI completely rewritten using Qt5. Replaces old GTK GUI.
  • +
  • New Qt GUI now contains most of the debug tools that previously only existed in windows version.
  • +
  • Build setup migrated to cmake. Replaces scons build setup.
  • +
+


+

+

Created with the Personal Edition of HelpNDoc: Create help files for the Qt Help Framework

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Overview.html b/web/help/Overview.html index c9a0b8a7..1e9c1409 100644 --- a/web/help/Overview.html +++ b/web/help/Overview.html @@ -1,78 +1,269 @@ - - + + + + + - Overview - - - - - - - - - - + + + + + + + + Overview + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Overview

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

FCEUX

-


-

FCEUX is a cross platform, NTSC and PAL Famicom/NES and Dendy emulator that is an evolution of the original FCE Ultra emulator.  Over time FCE Ultra had separated into many separate branches.  

-


-

The concept behind FCEUX is to merge elements from FCEU Ultra, FCEU rerecording, FCEUXD, FCEUXDSP, FCEUXDSP CE, and FCEU-mm into a single branch of FCEU.  As the X implies, it is an all-encompassing version of the FCEU emulator that provides the best of all worlds for the general player, the ROM-hacking community, and the Tool-Assisted Speedrun Community.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Free CHM Help documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Overview

+ +
+ +

+

FCEUX

+


+

FCEUX is a cross platform, NTSC and PAL Famicom/NES and Dendy emulator that is an evolution of the original FCE Ultra emulator.  Over time FCE Ultra had separated into many separate branches.  

+


+

The concept behind FCEUX is to merge elements from FCEU Ultra, FCEU rerecording, FCEUXD, FCEUXDSP, FCEUXDSP CE, and FCEU-mm into a single branch of FCEU.  As the X implies, it is an all-encompassing version of the FCEU emulator that provides the best of all worlds for the general player, the ROM-hacking community, and the Tool-Assisted Speedrun Community.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Write EPub books for the iPad

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/OverviewofIncludedScripts.html b/web/help/OverviewofIncludedScripts.html index f8587344..5619bd32 100644 --- a/web/help/OverviewofIncludedScripts.html +++ b/web/help/OverviewofIncludedScripts.html @@ -1,130 +1,320 @@ - - + + + + + - Overview of Included Scripts - - - - - - - - - - + + + + + + + + Overview of Included Scripts + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Overview of Included Scripts

- -
- Lua Scripting ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Overview of Included Scripts

+ +
+

-

(written by FatRatKnight)

-


-

Overview of Included Scripts

-


-

Many users of FCEUX do not investigate the luaScripts folder, or, for that matter, ignore lua scripting altogether. The purpose of this text is to let users know that knowing how to create lua scripts is not a requirement in using them. Indeed, there are several scripts that, if you just load them, will explain themselves enough that you don't need to know how to program at all in order to use them. Besides, they shouldn't need to be re-programmed anyway if you are to use them, for if they needed programming experience just to be used, their existence is largely defeated by that very fact!

-


-

FCEUX itself is a program that you load. Our amazing programmers did all the work already so you don't need to program up your own FCEUX to run it, do you? The same can be said of these scripts.

-


-

So, open the luaScripts folder and actually take the time to look at some of these scripts. You may use a text-editing program to open these if you so wish.

-


-


-

General Purpose scripts:

-

These may be used with any game freely. Else, the "General" part of General Purpose doesn't apply.

-


-
    -
  • Mutlitrack2.lua        -        Tracks future input that FCEUX promptly loses on state-load, for TAS
  • -
  • Subtitler.lua                -        For easier use of FCEUX's built-in subtitles for .fm2 files
  • -
  • Rewinder.lua        -        A way to rewind backwards by pressing a button
  • -
  • Sprites.lua        -        Sprite debugging highlights all sprites on screen, with mouse hover to inspect.
  • +

    (written by FatRatKnight)

    +


    +

    Overview of Included Scripts

    +


    +

    Many users of FCEUX do not investigate the luaScripts folder, or, for that matter, ignore lua scripting altogether. The purpose of this text is to let users know that knowing how to create lua scripts is not a requirement in using them. Indeed, there are several scripts that, if you just load them, will explain themselves enough that you don't need to know how to program at all in order to use them. Besides, they shouldn't need to be re-programmed anyway if you are to use them, for if they needed programming experience just to be used, their existence is largely defeated by that very fact!

    +


    +

    FCEUX itself is a program that you load. Our amazing programmers did all the work already so you don't need to program up your own FCEUX to run it, do you? The same can be said of these scripts.

    +


    +

    So, open the luaScripts folder and actually take the time to look at some of these scripts. You may use a text-editing program to open these if you so wish.

    +


    +


    +

    General Purpose scripts:

    +

    These may be used with any game freely. Else, the "General" part of General Purpose doesn't apply.

    +


    +
      +
    • Mutlitrack2.lua        -        Tracks future input that FCEUX promptly loses on state-load, for TAS
    • +
    • Subtitler.lua                -        For easier use of FCEUX's built-in subtitles for .fm2 files
    • +
    • Rewinder.lua        -        A way to rewind backwards by pressing a button
    -


    -


    -

    Game Specific scripts:

    -

    These scripts are built specifically for certain games. Attempting to run them while you've loaded another ROM will likely cause undesired results. The meaning of "undesired results" in this case are things like crashing the game, causing it to glitch in other ways, or having nonsense numbers and pixels show up.

    -


    -
      -
    • BugsBunnyBirthdayBlowout.lua
    • -
    • Excitingbike.lua
    • -
    • Excitingbike-speedometeronly.lua
    • -
    • Galaxian.lua
    • -
    • Gradius-BulletHell.lua
    • -
    • Machrider.lua
    • -
    • MegamanII-LaserEyes.lua
    • -
    • PunchOutChallenge.lua
    • -
    • PunchOutStats.lua
    • -
    • PunchOutTraining.lua
    • -
    • SMB2U.lua
    • -
    • SMB3-RainbowRiding.lua
    • -
    • SMB-AreaScrambler.lua
    • -
    • SMB-CompetitionRecorder.lua
    • -
    • SMB-HitBoxes.lua
    • -
    • SMB-Jetpack.lua
    • -
    • SMB-Lives&HPDisplay.lua
    • -
    • SMB-Mouse.lua
    • -
    • SMB-Snow.lua
    • -
    • TeenageMutantNinjaTurtles.lua
    • -
    • tetris.lua
    • +


      +


      +

      Game Specific scripts:

      +

      These scripts are built specifically for certain games. Attempting to run them while you've loaded another ROM will likely cause undesired results. The meaning of "undesired results" in this case are things like crashing the game, causing it to glitch in other ways, or having nonsense numbers and pixels show up.

      +


      +
        +
      • BugsBunnyBirthdayBlowout.lua
      • +
      • Excitingbike.lua
      • +
      • Excitingbike-speedometeronly.lua
      • +
      • Galaxian.lua
      • +
      • Gradius-BulletHell.lua
      • +
      • Machrider.lua
      • +
      • MegamanII-LaserEyes.lua
      • +
      • PunchOutChallenge.lua
      • +
      • PunchOutStats.lua
      • +
      • PunchOutTraining.lua
      • +
      • SMB2U.lua
      • +
      • SMB3-RainbowRiding.lua
      • +
      • SMB-AreaScrambler.lua
      • +
      • SMB-CompetitionRecorder.lua
      • +
      • SMB-HitBoxes.lua
      • +
      • SMB-Jetpack.lua
      • +
      • SMB-Lives&HPDisplay.lua
      • +
      • SMB-Mouse.lua
      • +
      • SMB-Snow.lua
      • +
      • TeenageMutantNinjaTurtles.lua
      • +
      • tetris.lua
      -


      -


      -


      -

      Auxiliary Functions scripts:

      -

      These scripts exist to make the life of programmers easier. As such, if you don't program, you may skip over these scripts. These should not be run by themselves, for they themselves probably don't have any programming to do any work usefully. It's like giving yourself a clip of bullets with no gun to use.

      -


      -
        -
      • FRKfunctions.lua        -        To aid with input.get, display, and registers
      • -
      • x_functions.lua
      • -
      • shapedefs.lua        -        Contains a few shape-drawing functions
      • +


        +


        +


        +

        Auxiliary Functions scripts:

        +

        These scripts exist to make the life of programmers easier. As such, if you don't program, you may skip over these scripts. These should not be run by themselves, for they themselves probably don't have any programming to do any work usefully. It's like giving yourself a clip of bullets with no gun to use.

        +


        +
          +
        • FRKfunctions.lua        -        To aid with input.get, display, and registers
        • +
        • x_functions.lua
        • +
        • shapedefs.lua        -        Contains a few shape-drawing functions

        -

        Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

        -
- - + + +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + - -
- - diff --git a/web/help/PPU.html b/web/help/PPU.html index df7fafa5..ba8a9313 100644 --- a/web/help/PPU.html +++ b/web/help/PPU.html @@ -1,367 +1,558 @@ - - + + + + + - PPU - 2C02 - - - - - - - - - - + + + + + + + + PPU - 2C02 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

PPU - 2C02

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

*******************************

-

*NTSC 2C02 technical operation*

-

*******************************

-

Brad Taylor (big_time_software@hotmail.com)

-


-

1st release: Sept 25th, Y2K

-

2nd release: Jan  27th, 2K3

-

3rd release: Feb   4th, 2K3

-

4th release: Feb  19th, 2K3

-


-


-

This document describes the low-level operation and technical details of the 2C02, the NES's PPU. In general, it contains important information in regards to PPU timing, which no NES coder/emulator author should be without. This document assumes that you already understand the basics of how the PPU works, like how the playfield/object images are generated, and the behaviour of scroll/address counters during playfield rendering.

-


-

Alot of the concepts behind how the PPU works described here have been extracted from Nintendo's patent documentation (U.S.#4,824,106). With block diagrams of the PPU's architecture (and even some schematics), these papers will definetely aid in the comprehension of this complex device.

-


-

Since the first release, this document has been given a major overhaul. Most sections of the document have been reworked, and new information has been added just about everywhere. If you've read the old version of this document before, I recommend that you read this new one in it's entirity; there's new information even in sections which may look like they haven't changed much.

-


-

Topics discussed hereon are as follows.

-


-

- Video signal generation

-

- PPU base timing

-

- Miscellanious PPU info

-

- PPU memory access cycles

-

- Frame rendering details

-

- Scanline rendering details

-

- In-range object evaluation

-

- Details of playfield render pipeline

-

- Details of object pattern fetch & render

-

- Extra cycle frames

-

- The MMC3's scanline counter

-

- PPU pixel priority quirk

-

- Graphical enhancements

-


-


-

+-------+

-

|History|

-

+-------+

-

On the weekend of Sept. 25th, Y2K, I setup an experiment with my NTSC NES MB & my PC so's I could RE the PPU's timing. What I did was (using a PC interface) analyse the changes that occur on the PPU's address and data pins on every rising & falling edge of the PPU's clock. I was not planning on removing the PPU from the motherboard (yet), so basically I just kept everything intact (minus the stuff I added onto the MB so I could monitor the PPU's signals), and popped in a game, so that it would initialize the PPU for me (I used DK classics, since it was only taking somthing like 4 frames before it was turning on the background/sprites).

-


-

The only change I made was taking out the 21 MHz clock generator circuitry. To replace the clock signal, I connected a port controlled latch to the NES's main clock line instead. Now, by writing a 0 or a 1 out to an PC ISA port of my choice (I was using $104), I was able to control the 21 MHz clockline of the NES. After I would create a rise or a fall on the NES's clock line, I would then read in the data that appeared on the PPU's address and data pins, which included monitoring what PPU registers the game read/wrote to (& the data that was read/written).

-


-


-

+-----------------------+

-

|Video signal generation|

-

+-----------------------+

-

A 21.48 MHz clock signal is fed into the PPU. This is the NES's main clock line, which is shared by the CPU.

-


-

Inside the PPU, the 21.48 MHz signal is used to clock a three-stage Johnson counter. The complimentery outputs of both master and slave portions of each stage are used to form 12 mutually exclusive output phases- all 3.58 MHz each (the NTSC colorburst). These 12 different phases form the basis of all color generation for the PPU's composite video output.

-


-

Naturally, when the user programs the lower 4-bits of a palette register, they are essentially selecting any 1 of 12 phases to be routed to the PPU's video out pin (this corresponds to chrominance (tint/hue) video information) when the appropriate pixel indexes it. Other chrominance combinations (0 & 13) are simply hardwired to a 1 or 0 to generate grayscale pixels.

-


-

Bits 4 & 5 of a palette entry selects 1 of 4 linear DC voltage offsets to apply to the selected chrominance signal (this corresponds to luminance (brightness) video information) for a pixel.

-


-

Chrominance values 14 & 15 yield a black pixel color, regardless of any luminance value setting.

-


-

Luminance value 0, mixed with chrominance value 13 yield a "blacker than black" pixel color. This super black pixel has an output voltage level close to the vertical/horizontal syncronization pulses. Because of this, some video monitors will display warped/distorted screens for games which use this color for black (Game Genie is the best example of this). Essentially what is happening is the video monitor's horizontal timing is compromised by what it thinks are extra syncronization pulses in the scanline. This is not damaging to the monitors which are effected by it, but use of the super black color should be avoided, due to the graphical distortion it causes.

-


-

The amplitude of the selected chrominance signal (via the 4 lower bits of a palette register) remain constant regardless of bits 4 or 5. Thus it is not possible to adjust the saturation level of a particular color.

-


-


-

+---------------+

-

|PPU base timing|

-

+---------------+

-

Other than the 3-stage Johnson counter, the 21.48 MHz signal is not used directly by any other PPU hardware. Instead, the signal is divided by 4 to get 5.37 MHz, and is used as the smallest unit of timing in the PPU. All following references to PPU clock cycle (abbr. "cc") timing in this document will be in respect to this timing base, unless otherwise indicated.

-


-

- Pixels are rendered at the same rate as the base PPU clock. In other words, 1 clock cycle= 1 pixel.

-


-

- 341 PPU cc's make up the time of a typical scanline (or 341/3 CPU cc's).

-


-

- One frame consists of 262 scanlines. This equals 341*262 PPU cc's per frame (divide by 3 for # of CPU cc's).

-


-


-

+------------------------+

-

|PPU memory access cycles|

-

+------------------------+

-

All PPU memory access cycles are 2 clocks long, and can be made back-to-back (typically done during rendering). Here's how the access breaks down:

-


-

At the beginning of the access cycle, PPU address lines 8..13 are updated with the target address. This data remains here until the next time an access cycle occurs.

-


-

The lower 8-bits of the PPU address lines are multiplexed with the data bus, to reduce the PPU's pin count. On the first clock cycle of the access, A0..A7 are put on the PPU's data bus, and the ALE (address latch enable) line is activated for the first half of the cycle. This loads the lower 8-bit address into an external 8-bit transparent latch strobed by ALE (74LS373 is used).

-


-

On the second clock cycle, the /RD (or /WR) line is activated, and stays active for the entire cycle. Appropriate data is driven onto the bus during this time.

-


-


-

+----------------------+

-

|Miscellanious PPU info|

-

+----------------------+

-

- Sprite DMA is 1536 clock cycles long (512 CPU cc's). 256 individual transfers are made from CPU memory to a temp register inside the CPU, then from the CPU's temp reg, to $2004.

-


-

- The PPU makes NO external access to the PPU bus, unless the playfield or objects are enabled during a scanline outside vblank. This means that the PPU's address and data busses are dead while in this state.

-


-

- palette RAM is accessed internally during playfield rendering (i.e., the palette address/data is never put on the PPU bus during this time). Additionally, when the programmer accesses palette RAM via $2006/7, the palette address accessed actually does show up on the PPU address bus, but the PPU's /RD & /WR flags are not activated. This is required; to prevent writing over name table data falling under the approprite mirrored area (since the name table RAM's address decoder simply consists of an inverter connected to the A13 line- effectively decoding all addresses in $2000-$3FFF).

-


-

- the VINT impulse (NMI) and bit $2002.7 are set simultaniously. Reading $2002 will reset bit 7, but it seems that the VINT flag goes down on it's own. Because of this, when the PPU generates a VINT, it doesn't require any acknowledgement whatsoever; it will continue firing off VINTs, regardless of inservice to $2002. The only way to stop VINTs is to clear $2000.7.

-


-

- Because the PPU cannot make a read from PPU memory immediately upon request (via $2007), there is an internal buffer, which acts as a 1-stage data pipeline. As a read is requested, the contents of the read buffer are returned to the NES's CPU. After this, at the PPU's earliest convience (according to PPU read cycle timings), the PPU will fetch the requested data from the PPU memory, and throw it in the read buffer. Writes to PPU mem via $2007 are pipelined as well, but it is unknown to me if the PPU uses this same buffer (this could be easily tested by writing somthing to $2007, and seeing if the same value is returned immediately after reading).

-


-


-

+-----------------------+

-

|Frame rendering details|

-

+-----------------------+

-

 The following describes the PPU's status during all 262 scanlines of a frame. Any scanlines where work is done (like image rendering), consists of the steps which will be described in the next section.

-


-

0..19:        Starting at the instant the VINT flag is pulled down (when a NMI is generated), 20 scanlines make up the period of time on the PPU which I like to call the VINT period. During this time, the PPU makes no access to it's external memory (i.e. name / pattern tables, etc.).

-


-

20:        After 20 scanlines worth of time go by (since the VINT flag was set), the PPU starts to render scanlines. This first scanline is a dummy one; although it will access it's external memory in the same sequence it would for drawing a valid scanline, no on-screen pixels are rendered during this time, making the fetched background data immaterial. Both horizontal *and* vertical scroll counters are updated (presumably) at cc offset 256 in this scanline. Other than that, the operation of this scanline is identical to any other. The primary reason this scanline exists is to start the object render pipeline, since it takes 256 cc's worth of time to determine which objects are in range or not for any particular scanline.

-


-

21..260: after rendering 1 dummy scanline, the PPU starts to render the actual data to be displayed on the screen. This is done for 240 scanlines, of course.

-


-

261:        after the very last rendered scanline finishes, the PPU does nothing for 1 scanline (i.e. the programmer gets screwed out of perfectly good VINT time). When this scanline finishes, the VINT flag is set, and the process of drawing lines starts all over again.

-


-


-

+--------------------------+

-

|Scanline rendering details|

-

+--------------------------+

-

Naturally, the PPU will fetch data from name, attribute, and pattern tables during a scanline to produce an image on the screen. This section details the PPU's doings during this time.

-


-

As explained before, external PPU memory can be accessed every 2 cc's. With 341 cc's per scanline, this gives the PPU enough time to make 170 memory accesses per scanline (and it uses all of them!). After the 170th fetch, the PPU does nothing for 1 clock cycle. Remember that a single pixel is rendered every clock cycle.

-


-


-

Memory fetch phase 1 thru 128

-

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

-

1. Name table byte

-

2. Attribute table byte

-

3. Pattern table bitmap #0

-

4. Pattern table bitmap #1

-


-

This process is repeated 32 times (32 tiles in a scanline).

-


-


-

This is when the PPU retrieves the appropriate data from PPU memory for rendering the playfield. The first playfield tile fetched here is actually the 3rd to be drawn on the screen (the playfield data for the first 2 tiles to be rendered on this scanline are fetched at the end of the scanline prior to this one).

-


-

All valid on-screen pixel data arrives at the PPU's video out pin during this time (256 clocks). For determining the precise delay between when a tile's bitmap fetch phase starts (the whole 4 memory fetches), and when the first pixel of that tile's bitmap data hits the video out pin, the formula is (16-n) clock cycles, where n is the fine horizontal scroll offset (0..7 pixels). This information is relivant for understanding the exact timing operation of the "object 0 collision" flag.

-


-

Note that the PPU fetches an attribute table byte for every 8 sequential horizontal pixels it draws. This essentially limits the PPU's color area (the area of pixels which are forced to use the same 3-color palette) to only 8 horizontally sequential pixels.

-


-

It is also during this time that the PPU evaluates the "Y coordinate" entries of all 64 objects in object attribute RAM (OAM), to see if the objects are within range (to be drawn on the screen) for the *next* scanline (this is why Y-coordinate entries in the OAM must be programmed to a value 1 less than the scanline the object is to appear on). Each evaluation (presumably) takes 4 clock cycles, for a total of 256 (which is why it's done during on-screen pixel rendering).

-


-


-

In-range object evaluation

-

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

-

An 8-bit comparator is used to calculate the 9-bit difference between the current scanline (minus 21), and each Y-coordinate (plus 1) of every object entry in the OAM. Objects are considered in range if the comparator produces a difference in the range of 0..7 (if $2000.5 currently = 0), or 0..15 (if $2000.5 currently = 1).

-


-

(Note that a 9-bit comparison result is generated. This means that setting object scanline coordinates for ranges -1..-15 are actually interpreted as ranges 241..255. For this reason, objects with these ranges will never be considered to be part of any on-screen scanline range, and will not allow smooth object scrolling off the top of the screen.)

-


-

Tile index (8 bits), X-coordinate (8 bits), & attribute information (4 bits; vertical inversion is excluded) from the in-range OAM element, plus the associated 4-bit result of the range comparison accumulate in a part of the PPU called the "sprite temporary memory". Logical inversion is applied to the loaded 4-bit range comparison result, if the object's vertical inversion attribute bit is set.

-


-

Since object range evaluations occur sequentially through the OAM (starting from entry 0 to 63), the sprite temporary memory always fills in order from the highest priority in-range object, to lower ones. A 4-bit "in-range" counter is used to determine the number of found objects on the scanline (from 0 up to 8), and serves as an index pointer for placement of found object data into the 8-element sprite temporary memory. The counter is reset at the beginning of the object evaluation phase, and is post-incremented everytime an object is found in-range. This occurs until the counter equals 8, when found object data after this is discarded, and a flag (bit 5 of $2002) is raised, indicating that it is going to be dropping objects for the next scanline.

-


-

An additional memory bit associated with the sprite temporary memory is used to indicate that the primary object (#0) was found to be in range. This will be used later on to detect primary object-to-playfield pixel collisions.

-


-


-

Playfield render pipeline details

-

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

-

As pattern table & palette select data is fetched, it is loaded into internal latches (the palette select data is selected from the fetched byte via a 2-bit 1-of-4 selector).

-


-

At the start of a new tile fetch phase (every 8 cc's), both latched pattern table bitmaps are loaded into the upper 8-bits of 2- 16-bit shift registers (which both shift right every clock cycle). The palette select data is also transfered into another latch during this time (which feeds the serial inputs of 2 8-bit right shift registers shifted every clock). The pixel data is fed into these extra shift registers in order to implement fine horizontal scrolling, since the periods when the PPU fetch tile data is fixed.

-


-

A single bit from each shift register is selected, to form the valid 4-bit playfield pixel for the current clock cycle. The bit selection offset is based on the fine horizontal scroll value (this selects bit positions 0..7 for all 4 shift registers). The selected 4-bit pixel data will then be fed into the multiplexer (described later) to be mixed with object data.

-


-


-

Memory fetch phase 129 thru 160

-

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

-

1. Garbage name table byte

-

2. Garbage name table byte

-

3. Pattern table bitmap #0 for applicable object (for next scanline)

-

4. Pattern table bitmap #1 for applicable object (for next scanline)

-


-

This process is repeated 8 times.

-


-


-

This is the period of time when the PPU retrieves the appropriate pattern table data for the objects to be drawn on the *next* scanline. When less than 8 objects exist on the next scanline (as the in-range object evaluation counter indicates), dummy pattern table fetches take place for the remaining fetches. Internally, the fetched dummy-data is discarded, and replaced with completely transparent bitmap patterns).

-


-

Although the fetched name table data is thrown away, and the name table address is somewhat unpredictable, the address does seem to relate to the first name table tile to be fetched for the next scanline. This would seem to imply that PPU cc #256 is when the PPU's scroll/address counters have their horizontal scroll values automatically updated.

-


-

It should also be noted that because this fetch is required for objects on the next scanline, it is neccessary for a garbage scanline to exist prior to the very first scanline to be actually rendered, so that object attribute RAM entries can be evaluated, and the appropriate bitmap data retrieved.

-


-

As far as the wasted fetch phases here, well, what can I say. Either Nintendo's engineers were VERY lazy, and didn't want to add the small amount of extra circuitry to the PPU so that 16 object fetches could take place per scanline, or Nintendo couldn't spot the extra memory required to implement 16 object scanlines. Thing is though- between the object attribute mem, sprite temporary & buffer mem, and palette mem, that's already 2406 bits of RAM; I don't think it would've killed them to just add the 408 bits it would've took for an extra 8 objects, which would've made games with horrible OAM cycling (Double Dragon 2 w/ 2 players) look half-decent (hell, with 16 object scanlines, games would hardly even need OAM cycling).

-


-

-

Details of object pattern fetch & render

-

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

-

Where the PPU fetches pattern table data for an individual object is conditioned on the contents of the sprite temporary memory element, and $2000.5. If $2000.5 = 0, the tile index data is used as usual, and $2000.3 selects the pattern table to use. If $2000.5 = 1, the MSB of the range result value become the LSB of the indexed tile, and the LSB of the tile index value determines pattern table selection. The lower 3 bits of the range result value are always used as the fine vertical offset into the selected pattern.

-


-

Horizontal inversion (bit order reversing) is applied to fetched bitmaps, if indicated in the sprite temporary memory element.

-


-

The fetched pattern table data (which is 2 bytes), plus the associated 3 attribute bits (palette select & priority), and the x coordinate byte in sprite temporary memory are then loaded into a part of the PPU called the "sprite buffer memory" (the primary object present bit is also copied). This memory area again, is large enough to hold the contents for 8 sprites.

-


-

The composition of one sprite buffer element here is: 2 8-bit shift registers (the fetched pattern table data is loaded in here, where it will be serialized at the appropriate time), a 3-bit latch (which holds the color & priority data for an object), and an 8-bit down counter (this is where the x coordinate is loaded).

-


-

The counter is decremented every time the PPU renders a pixel (the first 256 cc's of a scanline; see "Memory fetch phase 1 thru 128" above). When the counter equals 0, the pattern table data in the shift registers will start to serialize (1 shift per clock). Before this time, or 8 clocks after, consider the outputs of the serializers for each stage to be 0 (transparency).

-


-

The streams of all 8 object serializers are prioritized, and ultimately only one stream (with palette select & priority information) is selected for output to the multiplexer (where object & playfield pixels are prioritized).

-


-

The data for the first sprite buffer entry (including the primary object present flag) has the first chance to enter the multiplexer, if it's output pixel is non-transparent (non-zero). Otherwise, priority is passed to the next serializer in the sprite buffer memory, and the test for non-transparency is made again (the primary object present status will always be passed to the multiplexer as false in this case). This is done until the last (8th) stage is reached, when the object data is passed through unconditionally. Keep in mind that this whole process occurs every clock cycle (hardware is used to determine priority instantly).

-


-

The multiplexer does 2 things: determines primary object collisions, and decides which pixel data to pass through to index the palette RAM- either the playfield's or the object's.

-


-

Primary object collisions occur when a non-transparent playfield pixel coincides with a non-transparent object pixel, while the primary object present status entering the multiplexer for the current clock cycle is true. This causes a flip-flop ($2002.6) to be set, and remains set (presumably) some time after the VINT occurence (prehaps up until scanline 20?).

-


-

The decision for selecting the data to pass through to the palette index is made rather easilly. The condition to use object (opposed to playfield) data is:

-


-

(OBJpri=foreground OR PFpixel=xparent) AND OBJpixel<>xparent

-


-

Since the PPU has 2 palettes; one for objects, and one for playfield, the appropriate palette will be selected depending on which pixel data is passed through.

-


-

After the palette look-up, the operation of events follows the aforementioned steps in the "video signal generation" section.

-


-


-

Memory fetch phase 161 thru 168

-

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

-

1. Name table byte

-

2. Attribute table byte

-

3. Pattern table bitmap #0 (for next scanline)

-

4. Pattern table bitmap #1 (for next scanline)

-


-

This process is repeated 2 times.

-


-


-

It is during this time that the PPU fetches the appliciable playfield data for the first and second tiles to be rendered on the screen for the *next* scanline. These fetches initialize the internal playfield pixel pipelines (2- 16-bit shift registers) with valid bitmap data. The rest of tiles (3..32) are fetched at the beginning of the following scanline.

-


-


-

Memory fetch phase 169 thru 170

-

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

-

1. Name table byte

-

2. Name table byte

-


-


-

I'm unclear of the reason why this particular access to memory is made. The name table address that is accessed 2 times in a row here, is also the same nametable address that points to the 3rd tile to be rendered on the screen (or basically, the first name table address that will be accessed when the PPU is fetching playfield data on the next scanline).

-


-


-

After memory access 170

-

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

-

The PPU simply rests for 1 cycle here (or the equivelant of half a memory access cycle) before repeating the whole pixel/scanline rendering process.

-


-


-

+------------------+

-

|Extra cycle frames|

-

+------------------+

-

Scanline 20 is the only scanline that has variable length. On every odd frame, this scanline is only 340 cycles (the dead cycle at the end is removed). This is done to cause a shift in the NTSC colorburst phase.

-


-

You see, a 3.58 MHz signal, the NTSC colorburst, is required to be modulated into a luminance carrying signal in order for color to be generated on an NTSC monitor. Since the PPU's video out consists of basically square waves (as opposed to sine waves, which would be preferred), it takes an entire colorburst cycle (1/3.58 MHz) for an NTSC monitor to identify the color of a PPU pixel accurately.

-


-

But now you remember that the PPU renders pixels at 5.37 MHz- 1.5x the rate of the colorburst. This means that if a single pixel resides on a scanline with a color different to those surrounding it, the pixel will probably be misrepresented on the screen, sometimes appearing faintly.

-


-

Well, to somewhat fix this problem, they added this extra pixel into every odd frame (shifting the colorburst phase over a bit), and changing the way the monitor interprets isolated colored pixels each frame. This is why when you play games with detailed background graphics, the background seems to flicker a bit. Once you start scrolling the screen however, it seems as if some pixels become invisible; this is how stationary PPU images would look without this cycle removed from odd frames.

-


-

Certain scroll rates expose this NTSC PPU color caveat regardless of the toggling phase shift. Some of Zelda 2's dungeon backgrounds are a good place to see this effect.

-


-


-

+---------------------------+

-

|The MMC3's scanline counter|

-

+---------------------------+

-

As most people know, the MMC3 bases it's scanline counter on PPU address line A13 (which is why IRQ's can be fired off manually by toggling A13 a bunch of times via $2006). What's not common knowledge is the number of times A13 is expected to toggle in a scanline (although if you've been paying close attention to the doc here, you should already know ;)

-


-

A13 was probably used for the IRQ counter (as opposed to using the PPU's /READ line) because this address line already needed to be connected to the MMC for bankswitching purposes (so in other words, to reduce the MMC3's pin count by 1). They also probably used this method of counting (as opposed to a CPU cycle counter) since A13 cycles (0 -> 1) exactly 42 times per scanline, whereas the CPU count of cycles per scanline is not an exact integer (113.67). Having said that, I guess Nintendo wanted to provide an "easy-to-use" method of generating special image effects, without making programmers have to figure out how many clock cycles to program an IRQ counter with (a pretty lame excuse for not providing an IRQ counter with CPU clock cycle precision (which would have been more useful and versatile)).

-


-

Regardless of any values PPU registers are programmed with, A13 will operate in a predictable fashion during image rendering (and if you understand how PPU addressing works, you should understand that A13 is the *only* address line with fixed behaviour during image rendering).

-


-


-

+------------------------+

-

|PPU pixel priority quirk|

-

+------------------------+

-

Object data is prioritized between itself, then prioritized between the playfield. There are some odd side effects to this scheme of rendering, however. For instance, imagine a low priority object pixel with foreground priority, a high priority object pixel with background priority, and a playfield pixel all coinciding (all non-transparent).

-


-

Ideally, the playfield is considered to be the middle layer between background and foreground priority objects. This means that the playfield pixel should hide the background priority object pixel (regardless of object priority), and the foreground priority object should appear atop the PF pixel.

-


-

However, because of the way the PPU renders (as just described), OBJ priority is evaluated first, and therefore the background object pixel wins, which means that you'll only be seeing the PF pixel after this mess.

-


-

A good game to demonstrate this behaviour is Megaman 2. Go into airman's stage. First, jump into the energy bar, just to confirm that megaman's sprite is of a higher priority than the energy bar's. Now, get to the second half of the stage, where the clouds cover the energy bar. The energy bar will be ontop of the clouds, but megaman will be behind them. Now, look what happens when you jump into the energy bar here... you see the clouds where megaman underlaps the energy bar.

-


-


-

+----------------------+

-

|Graphical enhancements|

-

+----------------------+

-

Since an NES cartridge has access to the PPU bus, any number of on-cart hardware schemes can be used to enhance the graphic capabilities of the NES. After all, the PPU's playfield pipeline is very simple: it fetches 272 playfield pixels per scanline (as 34*2 byte fetches, in real-time), and outputs 256 of them to the screen (with the 0..7 pixel offset determined by the fine X scroll register), along with object data combined with it.

-


-

Essentially, you can bypass the PPU's simple scrolling system, implement a custom one on your cart (fetching bitmap data in your own fashion), and feed the PPU bitmap data in your own order.

-


-

The possibilities of this are endless (like sporting multiple playfields, or even playfield rotation/scaling), but of course what it comes down to is the amount of cartridge hardware required.

-


-

Generally, playfield rotation/scaling can be done quite easily- it only requires a few sets of 16-bit registers and adders (the 16 bits are broken up into 8.8 fixed point values). But this kind of implementation is more suited for an integrated circuit, since this would require dozens of discrete logic chips.

-


-

Multiple playfields are another thing which could be easily done. The caveat here is that pixel pipelines (i.e., shift registers) and a multiplexer would have to be implemented on the cart (not to mention exclusive name table RAM) in order to process the playfield bitmaps from multiple sources. The access to the CHR-ROM/RAM would also have to increased- but as it stands, the CHR-ROM/RAM bandwidth is 1.34 MHz, a rather low frequency. With a memory device capable of a 10.74 MHz bandwith, you could have 8 playfields to work with. Generally, this would be very useful for displaying multiple huge objects on the screen- without ever having to worry about annoying flicker.

-


-

The only restriction to doing any of this is that:

-


-

- every 8 sequential horizontal pixels sent to the PPU must share the same palette select value. Because of this, hardware would have to be implemented to decide which palette select value to feed the PPU between 8 horizontally sequential pixels, if they do not all share the same palette select value. The on-screen results of this may not be too flattering sometimes, but this is a small price to pay to do some neat graphical tricks on the NES.

-


-

-only the playfield palette can be used. As usual, this pretty much limits your randomly accessable colors to about 12+1.

-


-

It's a damn shame that Nintendo never created a MMC which would enhance graphics on the NES in useful ways as mentioned above. The MMC5 was the only device that came close, and it's only selling features were the single-tile color area, and the vertical split screen mode (which I don't think any game ever used). Considering the amount of pins (100) the MMC5 had, and number of gates they put in it just for the EXRAM (which was 1K bytes), they could've put some really useful graphics hardware inside there instead.

-


-

Prehaps the infamous Color Dreams "Hellraiser" cart was the closest the NES ever came to seeing such sophisticated graphics. The cart was never released, but from what I've read, it was going to use some sort of frame buffer, and a Z80 CPU to do the graphical rendering. It had been rumored that the game had 3D graphics (or at least 2.5D) in it. If so (and the game was actually good), prehaps it would have raised a few eyebrows in the industry, and inspired Nintendo to develop a new MMC chip with similar capabilities, in order to keep the NES in it's profit margin for another few years (and allow it to compete somewhat with the more advanced systems of the time).

-


-

EOF

-

-

Created with the Personal Edition of HelpNDoc: Easily create CHM Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

PPU - 2C02

+ +
+ +

+

*******************************

+

*NTSC 2C02 technical operation*

+

*******************************

+

Brad Taylor (big_time_software@hotmail.com)

+


+

1st release: Sept 25th, Y2K

+

2nd release: Jan  27th, 2K3

+

3rd release: Feb   4th, 2K3

+

4th release: Feb  19th, 2K3

+


+


+

 This document describes the low-level operation and technical details of the 2C02, the NES's PPU. In general, it contains important information in regards to PPU timing, which no NES coder/emulator author should be without. This document assumes that you already understand the basics of how the PPU works, like how the playfield/object images are generated, and the behaviour of scroll/address counters during playfield rendering.

+


+

 Alot of the concepts behind how the PPU works described here have been extracted from Nintendo's patent documentation (U.S.#4,824,106). With block diagrams of the PPU's architecture (and even some schematics), these papers will definetely aid in the comprehension of this complex device.

+


+

 Since the first release, this document has been given a major overhaul. Most sections of the document have been reworked, and new information has been added just about everywhere. If you've read the old version of this document before, I recommend that you read this new one in it's entirity; there's new information even in sections which may look like they haven't changed much.

+


+

 Topics discussed hereon are as follows.

+


+

 - Video signal generation

+

 - PPU base timing

+

 - Miscellanious PPU info

+

 - PPU memory access cycles

+

 - Frame rendering details

+

 - Scanline rendering details

+

 - In-range object evaluation

+

 - Details of playfield render pipeline

+

 - Details of object pattern fetch & render

+

 - Extra cycle frames

+

 - The MMC3's scanline counter

+

 - PPU pixel priority quirk

+

 - Graphical enhancements

+


+


+

+-------+

+

|History|

+

+-------+

+

 On the weekend of Sept. 25th, Y2K, I setup an experiment with my NTSC NES MB & my PC so's I could RE the PPU's timing. What I did was (using a PC interface) analyse the changes that occur on the PPU's address and data pins on every rising & falling edge of the PPU's clock. I was not planning on removing the PPU from the motherboard (yet), so basically I just kept everything intact (minus the stuff I added onto the MB so I could monitor the PPU's signals), and popped in a game, so that it would initialize the PPU for me (I used DK classics, since it was only taking somthing like 4 frames before it was turning on the background/sprites).

+


+

 The only change I made was taking out the 21 MHz clock generator circuitry. To replace the clock signal, I connected a port controlled latch to the NES's main clock line instead. Now, by writing a 0 or a 1 out to an PC ISA port of my choice (I was using $104), I was able to control the 21 MHz clockline of the NES. After I would create a rise or a fall on the NES's clock line, I would then read in the data that appeared on the PPU's address and data pins, which included monitoring what PPU registers the game read/wrote to (& the data that was read/written).

+


+


+

+-----------------------+

+

|Video signal generation|

+

+-----------------------+

+

 A 21.48 MHz clock signal is fed into the PPU. This is the NES's main clock line, which is shared by the CPU.

+


+

 Inside the PPU, the 21.48 MHz signal is used to clock a three-stage Johnson counter. The complimentery outputs of both master and slave portions of each stage are used to form 12 mutually exclusive output phases- all 3.58 MHz each (the NTSC colorburst). These 12 different phases form the basis of all color generation for the PPU's composite video output.

+


+

 Naturally, when the user programs the lower 4-bits of a palette register, they are essentially selecting any 1 of 12 phases to be routed to the PPU's video out pin (this corresponds to chrominance (tint/hue) video information) when the appropriate pixel indexes it. Other chrominance combinations (0 & 13) are simply hardwired to a 1 or 0 to generate grayscale pixels.

+


+

 Bits 4 & 5 of a palette entry selects 1 of 4 linear DC voltage offsets to apply to the selected chrominance signal (this corresponds to luminance (brightness) video information) for a pixel.

+


+

 Chrominance values 14 & 15 yield a black pixel color, regardless of any luminance value setting. 

+


+

 Luminance value 0, mixed with chrominance value 13 yield a "blacker than black" pixel color. This super black pixel has an output voltage level close to the vertical/horizontal syncronization pulses. Because of this, some video monitors will display warped/distorted screens for games which use this color for black (Game Genie is the best example of this). Essentially what is happening is the video monitor's horizontal timing is compromised by what it thinks are extra syncronization pulses in the scanline. This is not damaging to the monitors which are effected by it, but use of the super black color should be avoided, due to the graphical distortion it causes.

+


+

 The amplitude of the selected chrominance signal (via the 4 lower bits of a palette register) remain constant regardless of bits 4 or 5. Thus it is not possible to adjust the saturation level of a particular color.

+


+


+

+---------------+

+

|PPU base timing|

+

+---------------+

+

 Other than the 3-stage Johnson counter, the 21.48 MHz signal is not used directly by any other PPU hardware. Instead, the signal is divided by 4 to get 5.37 MHz, and is used as the smallest unit of timing in the PPU. All following references to PPU clock cycle (abbr. "cc") timing in this document will be in respect to this timing base, unless otherwise indicated.

+


+

 - Pixels are rendered at the same rate as the base PPU clock. In other words, 1 clock cycle= 1 pixel.

+


+

 - 341 PPU cc's make up the time of a typical scanline (or 341/3 CPU cc's).

+


+

 - One frame consists of 262 scanlines. This equals 341*262 PPU cc's per frame (divide by 3 for # of CPU cc's).

+


+


+

+------------------------+

+

|PPU memory access cycles|

+

+------------------------+

+

 All PPU memory access cycles are 2 clocks long, and can be made back-to-back (typically done during rendering). Here's how the access breaks down:

+


+

 At the beginning of the access cycle, PPU address lines 8..13 are updated with the target address. This data remains here until the next time an access cycle occurs.

+


+

 The lower 8-bits of the PPU address lines are multiplexed with the data bus, to reduce the PPU's pin count. On the first clock cycle of the access, A0..A7 are put on the PPU's data bus, and the ALE (address latch enable) line is activated for the first half of the cycle. This loads the lower 8-bit address into an external 8-bit transparent latch strobed by ALE (74LS373 is used).

+


+

 On the second clock cycle, the /RD (or /WR) line is activated, and stays active for the entire cycle. Appropriate data is driven onto the bus during this time.

+


+


+

+----------------------+

+

|Miscellanious PPU info|

+

+----------------------+

+

 - Sprite DMA is 1536 clock cycles long (512 CPU cc's). 256 individual transfers are made from CPU memory to a temp register inside the CPU, then from the CPU's temp reg, to $2004.

+


+

 - The PPU makes NO external access to the PPU bus, unless the playfield or objects are enabled during a scanline outside vblank. This means that the PPU's address and data busses are dead while in this state.

+


+

 - palette RAM is accessed internally during playfield rendering (i.e., the palette address/data is never put on the PPU bus during this time). Additionally, when the programmer accesses palette RAM via $2006/7, the palette address accessed actually does show up on the PPU address bus, but the PPU's /RD & /WR flags are not activated. This is required; to prevent writing over name table data falling under the approprite mirrored area (since the name table RAM's address decoder simply consists of an inverter connected to the A13 line- effectively decoding all addresses in $2000-$3FFF).

+


+

 - the VINT impulse (NMI) and bit $2002.7 are set simultaniously. Reading $2002 will reset bit 7, but it seems that the VINT flag goes down on it's own. Because of this, when the PPU generates a VINT, it doesn't require any acknowledgement whatsoever; it will continue firing off VINTs, regardless of inservice to $2002. The only way to stop VINTs is to clear $2000.7.

+


+

 - Because the PPU cannot make a read from PPU memory immediately upon request (via $2007), there is an internal buffer, which acts as a 1-stage data pipeline. As a read is requested, the contents of the read buffer are returned to the NES's CPU. After this, at the PPU's earliest convience (according to PPU read cycle timings), the PPU will fetch the requested data from the PPU memory, and throw it in the read buffer. Writes to PPU mem via $2007 are pipelined as well, but it is unknown to me if the PPU uses this same buffer (this could be easily tested by writing somthing to $2007, and seeing if the same value is returned immediately after reading).

+


+


+

+-----------------------+

+

|Frame rendering details|

+

+-----------------------+

+

  The following describes the PPU's status during all 262 scanlines of a frame. Any scanlines where work is done (like image rendering), consists of the steps which will be described in the next section.

+


+

 0..19:        Starting at the instant the VINT flag is pulled down (when a NMI is generated), 20 scanlines make up the period of time on the PPU which I like to call the VINT period. During this time, the PPU makes no access to it's external memory (i.e. name / pattern tables, etc.).

+


+

 20:        After 20 scanlines worth of time go by (since the VINT flag was set), the PPU starts to render scanlines. This first scanline is a dummy one; although it will access it's external memory in the same sequence it would for drawing a valid scanline, no on-screen pixels are rendered during this time, making the fetched background data immaterial. Both horizontal *and* vertical scroll counters are updated (presumably) at cc offset 256 in this scanline. Other than that, the operation of this scanline is identical to any other. The primary reason this scanline exists is to start the object render pipeline, since it takes 256 cc's worth of time to determine which objects are in range or not for any particular scanline.

+


+

 21..260: after rendering 1 dummy scanline, the PPU starts to render the actual data to be displayed on the screen. This is done for 240 scanlines, of course.

+


+

 261:        after the very last rendered scanline finishes, the PPU does nothing for 1 scanline (i.e. the programmer gets screwed out of perfectly good VINT time). When this scanline finishes, the VINT flag is set, and the process of drawing lines starts all over again.

+


+


+

+--------------------------+

+

|Scanline rendering details|

+

+--------------------------+

+

 Naturally, the PPU will fetch data from name, attribute, and pattern tables during a scanline to produce an image on the screen. This section details the PPU's doings during this time.

+


+

 As explained before, external PPU memory can be accessed every 2 cc's. With 341 cc's per scanline, this gives the PPU enough time to make 170 memory accesses per scanline (and it uses all of them!). After the 170th fetch, the PPU does nothing for 1 clock cycle. Remember that a single pixel is rendered every clock cycle.

+


+


+

 Memory fetch phase 1 thru 128

+

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

+

 1. Name table byte

+

 2. Attribute table byte

+

 3. Pattern table bitmap #0

+

 4. Pattern table bitmap #1

+


+

 This process is repeated 32 times (32 tiles in a scanline).

+


+


+

 This is when the PPU retrieves the appropriate data from PPU memory for rendering the playfield. The first playfield tile fetched here is actually the 3rd to be drawn on the screen (the playfield data for the first 2 tiles to be rendered on this scanline are fetched at the end of the scanline prior to this one).

+


+

 All valid on-screen pixel data arrives at the PPU's video out pin during this time (256 clocks). For determining the precise delay between when a tile's bitmap fetch phase starts (the whole 4 memory fetches), and when the first pixel of that tile's bitmap data hits the video out pin, the formula is (16-n) clock cycles, where n is the fine horizontal scroll offset (0..7 pixels). This information is relivant for understanding the exact timing operation of the "object 0 collision" flag.

+


+

 Note that the PPU fetches an attribute table byte for every 8 sequential horizontal pixels it draws. This essentially limits the PPU's color area (the area of pixels which are forced to use the same 3-color palette) to only 8 horizontally sequential pixels.

+


+

 It is also during this time that the PPU evaluates the "Y coordinate" entries of all 64 objects in object attribute RAM (OAM), to see if the objects are within range (to be drawn on the screen) for the *next* scanline (this is why Y-coordinate entries in the OAM must be programmed to a value 1 less than the scanline the object is to appear on). Each evaluation (presumably) takes 4 clock cycles, for a total of 256 (which is why it's done during on-screen pixel rendering).

+


+


+

 In-range object evaluation

+

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

+

 An 8-bit comparator is used to calculate the 9-bit difference between the current scanline (minus 21), and each Y-coordinate (plus 1) of every object entry in the OAM. Objects are considered in range if the comparator produces a difference in the range of 0..7 (if $2000.5 currently = 0), or 0..15 (if $2000.5 currently = 1).

+


+

 (Note that a 9-bit comparison result is generated. This means that setting object scanline coordinates for ranges -1..-15 are actually interpreted as ranges 241..255. For this reason, objects with these ranges will never be considered to be part of any on-screen scanline range, and will not allow smooth object scrolling off the top of the screen.)

+


+

 Tile index (8 bits), X-coordinate (8 bits), & attribute information (4 bits; vertical inversion is excluded) from the in-range OAM element, plus the associated 4-bit result of the range comparison accumulate in a part of the PPU called the "sprite temporary memory". Logical inversion is applied to the loaded 4-bit range comparison result, if the object's vertical inversion attribute bit is set.

+


+

 Since object range evaluations occur sequentially through the OAM (starting from entry 0 to 63), the sprite temporary memory always fills in order from the highest priority in-range object, to lower ones. A 4-bit "in-range" counter is used to determine the number of found objects on the scanline (from 0 up to 8), and serves as an index pointer for placement of found object data into the 8-element sprite temporary memory. The counter is reset at the beginning of the object evaluation phase, and is post-incremented everytime an object is found in-range. This occurs until the counter equals 8, when found object data after this is discarded, and a flag (bit 5 of $2002) is raised, indicating that it is going to be dropping objects for the next scanline.

+


+

 An additional memory bit associated with the sprite temporary memory is used to indicate that the primary object (#0) was found to be in range. This will be used later on to detect primary object-to-playfield pixel collisions.

+


+


+

 Playfield render pipeline details

+

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

+

 As pattern table & palette select data is fetched, it is loaded into internal latches (the palette select data is selected from the fetched byte via a 2-bit 1-of-4 selector).

+


+

 At the start of a new tile fetch phase (every 8 cc's), both latched pattern table bitmaps are loaded into the upper 8-bits of 2- 16-bit shift registers (which both shift right every clock cycle). The palette select data is also transfered into another latch during this time (which feeds the serial inputs of 2 8-bit right shift registers shifted every clock). The pixel data is fed into these extra shift registers in order to implement fine horizontal scrolling, since the periods when the PPU fetch tile data is fixed.

+


+

 A single bit from each shift register is selected, to form the valid 4-bit playfield pixel for the current clock cycle. The bit selection offset is based on the fine horizontal scroll value (this selects bit positions 0..7 for all 4 shift registers). The selected 4-bit pixel data will then be fed into the multiplexer (described later) to be mixed with object data.

+


+


+

 Memory fetch phase 129 thru 160

+

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

+

 1. Garbage name table byte

+

 2. Garbage name table byte

+

 3. Pattern table bitmap #0 for applicable object (for next scanline)

+

 4. Pattern table bitmap #1 for applicable object (for next scanline)

+


+

 This process is repeated 8 times.

+


+


+

 This is the period of time when the PPU retrieves the appropriate pattern table data for the objects to be drawn on the *next* scanline. When less than 8 objects exist on the next scanline (as the in-range object evaluation counter indicates), dummy pattern table fetches take place for the remaining fetches. Internally, the fetched dummy-data is discarded, and replaced with completely transparent bitmap patterns).

+


+

 Although the fetched name table data is thrown away, and the name table address is somewhat unpredictable, the address does seem to relate to the first name table tile to be fetched for the next scanline. This would seem to imply that PPU cc #256 is when the PPU's scroll/address counters have their horizontal scroll values automatically updated.

+


+

 It should also be noted that because this fetch is required for objects on the next scanline, it is neccessary for a garbage scanline to exist prior to the very first scanline to be actually rendered, so that object attribute RAM entries can be evaluated, and the appropriate bitmap data retrieved.

+


+

 As far as the wasted fetch phases here, well, what can I say. Either Nintendo's engineers were VERY lazy, and didn't want to add the small amount of extra circuitry to the PPU so that 16 object fetches could take place per scanline, or Nintendo couldn't spot the extra memory required to implement 16 object scanlines. Thing is though- between the object attribute mem, sprite temporary & buffer mem, and palette mem, that's already 2406 bits of RAM; I don't think it would've killed them to just add the 408 bits it would've took for an extra 8 objects, which would've made games with horrible OAM cycling (Double Dragon 2 w/ 2 players) look half-decent (hell, with 16 object scanlines, games would hardly even need OAM cycling).

+


+

 

+

 Details of object pattern fetch & render

+

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

+

 Where the PPU fetches pattern table data for an individual object is conditioned on the contents of the sprite temporary memory element, and $2000.5. If $2000.5 = 0, the tile index data is used as usual, and $2000.3 selects the pattern table to use. If $2000.5 = 1, the MSB of the range result value become the LSB of the indexed tile, and the LSB of the tile index value determines pattern table selection. The lower 3 bits of the range result value are always used as the fine vertical offset into the selected pattern.

+


+

 Horizontal inversion (bit order reversing) is applied to fetched bitmaps, if indicated in the sprite temporary memory element.

+


+

 The fetched pattern table data (which is 2 bytes), plus the associated 3 attribute bits (palette select & priority), and the x coordinate byte in sprite temporary memory are then loaded into a part of the PPU called the "sprite buffer memory" (the primary object present bit is also copied). This memory area again, is large enough to hold the contents for 8 sprites.

+


+

 The composition of one sprite buffer element here is: 2 8-bit shift registers (the fetched pattern table data is loaded in here, where it will be serialized at the appropriate time), a 3-bit latch (which holds the color & priority data for an object), and an 8-bit down counter (this is where the x coordinate is loaded).

+


+

 The counter is decremented every time the PPU renders a pixel (the first 256 cc's of a scanline; see "Memory fetch phase 1 thru 128" above). When the counter equals 0, the pattern table data in the shift registers will start to serialize (1 shift per clock). Before this time, or 8 clocks after, consider the outputs of the serializers for each stage to be 0 (transparency).

+


+

 The streams of all 8 object serializers are prioritized, and ultimately only one stream (with palette select & priority information) is selected for output to the multiplexer (where object & playfield pixels are prioritized).

+


+

 The data for the first sprite buffer entry (including the primary object present flag) has the first chance to enter the multiplexer, if it's output pixel is non-transparent (non-zero). Otherwise, priority is passed to the next serializer in the sprite buffer memory, and the test for non-transparency is made again (the primary object present status will always be passed to the multiplexer as false in this case). This is done until the last (8th) stage is reached, when the object data is passed through unconditionally. Keep in mind that this whole process occurs every clock cycle (hardware is used to determine priority instantly).

+


+

 The multiplexer does 2 things: determines primary object collisions, and decides which pixel data to pass through to index the palette RAM- either the playfield's or the object's.

+


+

 Primary object collisions occur when a non-transparent playfield pixel coincides with a non-transparent object pixel, while the primary object present status entering the multiplexer for the current clock cycle is true. This causes a flip-flop ($2002.6) to be set, and remains set (presumably) some time after the VINT occurence (prehaps up until scanline 20?).

+


+

 The decision for selecting the data to pass through to the palette index is made rather easilly. The condition to use object (opposed to playfield) data is:

+


+

 (OBJpri=foreground OR PFpixel=xparent) AND OBJpixel<>xparent

+


+

 Since the PPU has 2 palettes; one for objects, and one for playfield, the appropriate palette will be selected depending on which pixel data is passed through.

+


+

 After the palette look-up, the operation of events follows the aforementioned steps in the "video signal generation" section.

+


+


+

 Memory fetch phase 161 thru 168

+

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

+

 1. Name table byte

+

 2. Attribute table byte

+

 3. Pattern table bitmap #0 (for next scanline)

+

 4. Pattern table bitmap #1 (for next scanline)

+


+

 This process is repeated 2 times.

+


+


+

 It is during this time that the PPU fetches the appliciable playfield data for the first and second tiles to be rendered on the screen for the *next* scanline. These fetches initialize the internal playfield pixel pipelines (2- 16-bit shift registers) with valid bitmap data. The rest of tiles (3..32) are fetched at the beginning of the following scanline.

+


+


+

 Memory fetch phase 169 thru 170

+

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

+

 1. Name table byte

+

 2. Name table byte

+


+


+

 I'm unclear of the reason why this particular access to memory is made. The name table address that is accessed 2 times in a row here, is also the same nametable address that points to the 3rd tile to be rendered on the screen (or basically, the first name table address that will be accessed when the PPU is fetching playfield data on the next scanline).

+


+


+

 After memory access 170

+

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

+

 The PPU simply rests for 1 cycle here (or the equivelant of half a memory access cycle) before repeating the whole pixel/scanline rendering process.

+


+


+

+------------------+

+

|Extra cycle frames|

+

+------------------+

+

 Scanline 20 is the only scanline that has variable length. On every odd frame, this scanline is only 340 cycles (the dead cycle at the end is removed). This is done to cause a shift in the NTSC colorburst phase.

+


+

 You see, a 3.58 MHz signal, the NTSC colorburst, is required to be modulated into a luminance carrying signal in order for color to be generated on an NTSC monitor. Since the PPU's video out consists of basically square waves (as opposed to sine waves, which would be preferred), it takes an entire colorburst cycle (1/3.58 MHz) for an NTSC monitor to identify the color of a PPU pixel accurately.

+


+

 But now you remember that the PPU renders pixels at 5.37 MHz- 1.5x the rate of the colorburst. This means that if a single pixel resides on a scanline with a color different to those surrounding it, the pixel will probably be misrepresented on the screen, sometimes appearing faintly.

+


+

 Well, to somewhat fix this problem, they added this extra pixel into every odd frame (shifting the colorburst phase over a bit), and changing the way the monitor interprets isolated colored pixels each frame. This is why when you play games with detailed background graphics, the background seems to flicker a bit. Once you start scrolling the screen however, it seems as if some pixels become invisible; this is how stationary PPU images would look without this cycle removed from odd frames.

+


+

 Certain scroll rates expose this NTSC PPU color caveat regardless of the toggling phase shift. Some of Zelda 2's dungeon backgrounds are a good place to see this effect.

+


+


+

+---------------------------+

+

|The MMC3's scanline counter|

+

+---------------------------+

+

 As most people know, the MMC3 bases it's scanline counter on PPU address line A13 (which is why IRQ's can be fired off manually by toggling A13 a bunch of times via $2006). What's not common knowledge is the number of times A13 is expected to toggle in a scanline (although if you've been paying close attention to the doc here, you should already know ;)

+


+

 A13 was probably used for the IRQ counter (as opposed to using the PPU's /READ line) because this address line already needed to be connected to the MMC for bankswitching purposes (so in other words, to reduce the MMC3's pin count by 1). They also probably used this method of counting (as opposed to a CPU cycle counter) since A13 cycles (0 -> 1) exactly 42 times per scanline, whereas the CPU count of cycles per scanline is not an exact integer (113.67). Having said that, I guess Nintendo wanted to provide an "easy-to-use" method of generating special image effects, without making programmers have to figure out how many clock cycles to program an IRQ counter with (a pretty lame excuse for not providing an IRQ counter with CPU clock cycle precision (which would have been more useful and versatile)).

+


+

 Regardless of any values PPU registers are programmed with, A13 will operate in a predictable fashion during image rendering (and if you understand how PPU addressing works, you should understand that A13 is the *only* address line with fixed behaviour during image rendering).

+


+


+

+------------------------+

+

|PPU pixel priority quirk|

+

+------------------------+

+

 Object data is prioritized between itself, then prioritized between the playfield. There are some odd side effects to this scheme of rendering, however. For instance, imagine a low priority object pixel with foreground priority, a high priority object pixel with background priority, and a playfield pixel all coinciding (all non-transparent).

+


+

 Ideally, the playfield is considered to be the middle layer between background and foreground priority objects. This means that the playfield pixel should hide the background priority object pixel (regardless of object priority), and the foreground priority object should appear atop the PF pixel.

+


+

 However, because of the way the PPU renders (as just described), OBJ priority is evaluated first, and therefore the background object pixel wins, which means that you'll only be seeing the PF pixel after this mess.

+


+

 A good game to demonstrate this behaviour is Megaman 2. Go into airman's stage. First, jump into the energy bar, just to confirm that megaman's sprite is of a higher priority than the energy bar's. Now, get to the second half of the stage, where the clouds cover the energy bar. The energy bar will be ontop of the clouds, but megaman will be behind them. Now, look what happens when you jump into the energy bar here... you see the clouds where megaman underlaps the energy bar.

+


+


+

+----------------------+

+

|Graphical enhancements|

+

+----------------------+

+

 Since an NES cartridge has access to the PPU bus, any number of on-cart hardware schemes can be used to enhance the graphic capabilities of the NES. After all, the PPU's playfield pipeline is very simple: it fetches 272 playfield pixels per scanline (as 34*2 byte fetches, in real-time), and outputs 256 of them to the screen (with the 0..7 pixel offset determined by the fine X scroll register), along with object data combined with it.

+


+

 Essentially, you can bypass the PPU's simple scrolling system, implement a custom one on your cart (fetching bitmap data in your own fashion), and feed the PPU bitmap data in your own order.

+


+

 The possibilities of this are endless (like sporting multiple playfields, or even playfield rotation/scaling), but of course what it comes down to is the amount of cartridge hardware required.

+


+

 Generally, playfield rotation/scaling can be done quite easily- it only requires a few sets of 16-bit registers and adders (the 16 bits are broken up into 8.8 fixed point values). But this kind of implementation is more suited for an integrated circuit, since this would require dozens of discrete logic chips.

+


+

 Multiple playfields are another thing which could be easily done. The caveat here is that pixel pipelines (i.e., shift registers) and a multiplexer would have to be implemented on the cart (not to mention exclusive name table RAM) in order to process the playfield bitmaps from multiple sources. The access to the CHR-ROM/RAM would also have to increased- but as it stands, the CHR-ROM/RAM bandwidth is 1.34 MHz, a rather low frequency. With a memory device capable of a 10.74 MHz bandwith, you could have 8 playfields to work with. Generally, this would be very useful for displaying multiple huge objects on the screen- without ever having to worry about annoying flicker.

+


+

 The only restriction to doing any of this is that:

+


+

 - every 8 sequential horizontal pixels sent to the PPU must share the same palette select value. Because of this, hardware would have to be implemented to decide which palette select value to feed the PPU between 8 horizontally sequential pixels, if they do not all share the same palette select value. The on-screen results of this may not be too flattering sometimes, but this is a small price to pay to do some neat graphical tricks on the NES.

+


+

 -only the playfield palette can be used. As usual, this pretty much limits your randomly accessable colors to about 12+1.

+


+

 It's a damn shame that Nintendo never created a MMC which would enhance graphics on the NES in useful ways as mentioned above. The MMC5 was the only device that came close, and it's only selling features were the single-tile color area, and the vertical split screen mode (which I don't think any game ever used). Considering the amount of pins (100) the MMC5 had, and number of gates they put in it just for the EXRAM (which was 1K bytes), they could've put some really useful graphics hardware inside there instead.

+


+

 Prehaps the infamous Color Dreams "Hellraiser" cart was the closest the NES ever came to seeing such sophisticated graphics. The cart was never released, but from what I've read, it was going to use some sort of frame buffer, and a Z80 CPU to do the graphical rendering. It had been rumored that the game had 3D graphics (or at least 2.5D) in it. If so (and the game was actually good), prehaps it would have raised a few eyebrows in the industry, and inspired Nintendo to develop a new MMC chip with similar capabilities, in order to keep the NES in it's profit margin for another few years (and allow it to compete somewhat with the more advanced systems of the time).

+


+

EOF

+

+

Created with the Personal Edition of HelpNDoc: Free Qt Help documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/PPUViewer.html b/web/help/PPUViewer.html index 8d2caed9..5b47e701 100644 --- a/web/help/PPUViewer.html +++ b/web/help/PPUViewer.html @@ -1,101 +1,291 @@ - - + + + + + - PPU Viewer - - - - - - - - - - + + + + + + + + PPU Viewer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

PPU Viewer

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

PPU Viewer

-


-


-

Introduction

-


-

The NES architecture includes a 6502 CPU as well as a custom video controller known as a PPU (Picture Processing Unit).  The PPU's video memory is separated from the main CPU memory and can be read/written via special ports (see PPU Memory).

-


-

The PPU viewer will only display the contents of the current PPU memory. It does not alter game data in any way.

-


-


-

Using PPU Viewer

-


-

Show on Scanline

-

This options makes it show what the PPU looks like when the screen is drawing that particular scanline. It is useful for games like SMB, that swap pattern tables mid-frame (e.g. for status bar stuff).

-


-

Right clicking on one of the PPU panels will change the palette it is shown with, cycling though pattern palettes, then sprite ones, then a ninth fixed grey palette (useful for inspecting CHR if all the palettes are currently black).

-


-

Putting the mouse cursor over a tile will display the tile address. Moving cursor over palette color will give palette address.

-


-

When Code/Data Logger is running, you can also use the "Mask unused graphics" feature. Alternatively, you can only mask tiles that were used (drawn or otherwise accessed) and emphasize the tiles that weren't used (e.g. in order to find secret sprites).

-

Note: this feature only works with games that use CHR ROM, because Code/Data Logger only logs accesses to CHR ROM.

-


-


-


-


-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Produce electronic books easily

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

PPU Viewer

+ +
+ +

+

PPU Viewer

+


+


+

Introduction

+


+

The NES architecture includes a 6502 CPU as well as a custom video controller known as a PPU (Picture Processing Unit).  The PPU's video memory is separated from the main CPU memory and can be read/written via special ports (see PPU Memory).

+


+

The PPU viewer will only display the contents of the current PPU memory. It does not alter game data in any way.

+


+


+

Using PPU Viewer

+


+

Show on Scanline

+

This options makes it show what the PPU looks like when the screen is drawing that particular scanline. It is useful for games like SMB, that swap pattern tables mid-frame (e.g. for status bar stuff).

+


+

Right clicking on one of the PPU panels will change the palette it is shown with, cycling though pattern palettes and then sprite ones.

+

Putting the mouse cursor over a tile will display the tile address. Moving cursor over palette color will give palette address.

+


+

When Code/Data Logger is running, you can also use the "Mask unused graphics" feature. Alternatively, you can only mask tiles that were used (drawn or otherwise accessed) and emphasize the tiles that weren't used (e.g. in order to find secret sprites).

+

Note: this feature only works with games that use CHR ROM, because Code/Data Logger only logs accesses to CHR ROM.

+


+


+


+


+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free help authoring tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Palette.html b/web/help/Palette.html index 9aa4242a..16017c00 100644 --- a/web/help/Palette.html +++ b/web/help/Palette.html @@ -1,118 +1,309 @@ - - + + + + + - Palette - - - - - - - - - - + + + + + + + + Palette + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Palette

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Palette

-


-

Settings related to the emulator's color palette choices.

-


-


-

NES Palette

-


-

Use Custom Palette

-

Check or uncheck this to switch between default palette and currently loaded custom palette.

-


-

Load Palette

-

Allows you to load a custom color palette (.pal) file to use for the current game loaded.

-


-

A note on on the format of external palettes; Palette files are expected to contain 64 8-bit RGB triplets (each in that order; red comes first in the triplet in the file, then green, then blue). Each 8-bit value represents brightness for that particular color. 0 is minimum, 255 is maximum.

-


-

Palettes can be set on a per-game basis. To do this, put a palette file in the same directory the game is in, and add the extension "pal". Examples:

-


-

                File name:              Palette file name:

-

                BigBad.nes             BigBad.pal

-

                BigBad.zip              BigBad.pal

-

                BigBad.Better.nes   BigBad.Better.pal

-


-


-

With so many ways to choose a palette, figuring out which one will be active may be difficult. Here's a list of what palettes will be used, in order from highest priority to least priority(if a condition doesn't exist for a higher priority palette, the emulator will continue down its list of palettes).

-


-

   * NSF Palette(for NSFs only)

-

   * Palette loaded from the "gameinfo" directory.

-

   * NTSC Color Emulation(only for NTSC NES games).

-

   * VS Unisystem palette(if the game is a VS Unisystem game and a palette is available).

-

   * Custom global palette.

-

   * Default NES palette.

-


-

Force Grayscale

-

Applies simple Grayscale filter, no matter what palette is currently used.

-


-

De-emphasis bit swap

-

Every PAL PPU has de-emphasis bits for green and red colors swapped. This option simulates that behavior.

-


-


-

NTSC Color Emulation

-


-

If enabled, FCEUX will simulate actual NTSC signal processing.  The result should be the actual colors you would see if outputting to an actual NTSC television.

-


-

The Tint and Hue knobs can be used to make adjustments to the resulting color change.

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free CHM Help documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Palette

+ +
+ +

+

Palette

+


+

Settings related to the emulator's color palette choices.

+


+


+

NES Palette

+


+

Use Custom Palette

+

Check or uncheck this to switch between default palette and currently loaded custom palette.

+


+

Load Palette

+

Allows you to load a custom color palette (.pal) file to use for the current game loaded.

+


+

A note on on the format of external palettes; Palette files are expected to contain 64 8-bit RGB triplets (each in that order; red comes first in the triplet in the file, then green, then blue). Each 8-bit value represents brightness for that particular color. 0 is minimum, 255 is maximum.

+


+

Palettes can be set on a per-game basis. To do this, put a palette file in the same directory the game is in, and add the extension "pal". Examples:

+


+

                 File name:              Palette file name:

+

                 BigBad.nes             BigBad.pal

+

                 BigBad.zip              BigBad.pal

+

                 BigBad.Better.nes   BigBad.Better.pal

+


+


+

With so many ways to choose a palette, figuring out which one will be active may be difficult. Here's a list of what palettes will be used, in order from highest priority to least priority(if a condition doesn't exist for a higher priority palette, the emulator will continue down its list of palettes).

+


+

    * NSF Palette(for NSFs only)

+

    * Palette loaded from the "gameinfo" directory.

+

    * NTSC Color Emulation(only for NTSC NES games).

+

    * VS Unisystem palette(if the game is a VS Unisystem game and a palette is available).

+

    * Custom global palette.

+

    * Default NES palette.

+


+

Force Grayscale

+

Applies simple Grayscale filter, no matter what palette is currently used.

+


+

De-emphasis bit swap

+

Every PAL PPU has de-emphasis bits for green and red colors swapped. This option simulates that behavior.

+


+


+

NTSC Color Emulation

+


+

If enabled, FCEUX will simulate actual NTSC signal processing.  The result should be the actual colors you would see if outputting to an actual NTSC television.

+


+

The Tint and Hue knobs can be used to make adjustments to the resulting color change.

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Create help files for the Qt Help Framework

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/PaletteOptions.html b/web/help/PaletteOptions.html index b3874bff..f400439e 100644 --- a/web/help/PaletteOptions.html +++ b/web/help/PaletteOptions.html @@ -1,108 +1,299 @@ - - + + + + + - Palette Options - - - - - - - - - - + + + + + + + + Palette Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Palette Options

- -
- General ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Palette Options

-


-

FCEUX comes packaged with several palette files. This page describes details for each one.

-

To load a palette file, see Palette config.

-


-


-

FCEUX.pal

-


-

This is the default palette that FCEUX uses. It is the same palette used in FCEU.12 or earlier, and FCEUD/FCEUXD/FCEUXDSP.

-


-

FCEU-13-default_nitsuja.pal

-


-

This is the palette added to FCEU.13 rerecording by Nitsuja.

-


-

FCEU-15-nitsuja-new.pal

-


-

This is the palette added to FCEU.15 rerecording by Nitsuja.  It is a slight adjustment to the FCEU.13 palette.

-


-

NESTOPIA_RGB.pal & NESTOPIA_YUV.pal

-


-

Default palettes of Nestopia.

-


-

BMF_final2.pal & BMF_final3.pal

-


-

These palettes were designed by BMF.  He customized these by looking at snapshots of his television screen and attempting to replicate them as close as possible.

-


-

ASQ_realityA.pal & ASQ_realityB.pal

-


-

BMF palettes had some flaws.  AspiringSquire tweaked BMF's palettes and came up with this.  They fix issues mostly related to brightness.

-


-

SONY_CXA2025AS_US.pal

-


-

This palette is based on the CXA2025AS integrated circuit used in Sony TV-sets.

-


-

Unsaturated-V6.pal

-


-

This palette by FirebrandX offers a more realistic brightness/contrast scale of the original console. It was developed using a direct-capture device hooked up to the NES, then error-corrected to the current and final 6th version.

-

-

Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Palette Options

+ +
+ +

+

Palette Options

+


+

FCEUX comes packaged with several palette files. This page describes details for each one.

+

To load a palette file, see Palette config.

+


+


+

FCEUX.pal

+


+

This is the default palette that FCEUX uses. It is the same palette used in FCEU.12 or earlier, and FCEUD/FCEUXD/FCEUXDSP.

+


+

FCEU-13-default_nitsuja.pal

+


+

This is the palette added to FCEU.13 rerecording by Nitsuja.

+


+

FCEU-15-nitsuja-new.pal

+


+

This is the palette added to FCEU.15 rerecording by Nitsuja.  It is a slight adjustment to the FCEU.13 palette.

+


+

NESTOPIA_RGB.pal & NESTOPIA_YUV.pal

+


+

Default palettes of Nestopia.

+


+

BMF_final2.pal & BMF_final3.pal

+


+

These palettes were designed by BMF.  He customized these by looking at snapshots of his television screen and attempting to replicate them as close as possible.

+


+

ASQ_realityA.pal & ASQ_realityB.pal

+


+

BMF palettes had some flaws.  AspiringSquire tweaked BMF's palettes and came up with this.  They fix issues mostly related to brightness.

+


+

SONY_CXA2025AS_US.pal

+


+

This palette is based on the CXA2025AS integrated circuit used in Sony TV-sets.

+


+

Unsaturated-V6.pal

+


+

This palette by FirebrandX offers a more realistic brightness/contrast scale of the original console. It was developed using a direct-capture device hooked up to the NES, then error-corrected to the current and final 6th version.

+

+

Created with the Personal Edition of HelpNDoc: Easy EBook and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/RAMSearch.html b/web/help/RAMSearch.html index 211f0890..6a7b3718 100644 --- a/web/help/RAMSearch.html +++ b/web/help/RAMSearch.html @@ -1,83 +1,274 @@ - - + + + + + - RAM Search - - - - - - - - - - + + + + + + + + RAM Search + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

RAM Search

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Ram Search

-


-

Ram Search is a tool originally written for GENS rerecording.  It was ported to FCEUX in version 2.1.2.  This dialog has also been ported to SNELS9x-rr, Desmume, PCEjin, VBA-rr, PCSX-rr, Yabause, VBjin, and FBA-rr.

-


-


-

It is designed to filter RAM values just like in the Cheat Search dialog.  However, it features many options that are lacking in the Cheat Search dialog.  Among these are search undo, search preview, a modulus filter, a data size option, signed/unsigned/hex options, autosearch, and several more compare by options.

-


-

Documentation on this dialog can be found on TASVideos here.

-


-

Hotkeys

-


-

Hotkeys can be assigned to common search commands so they can be easily selected while in the main window.

-

-

Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

RAM Search

+ +
+ +

+

Ram Search

+


+

Ram Search is a tool originally written for GENS rerecording.  It was ported to FCEUX in version 2.1.2.  This dialog has also been ported to SNELS9x-rr, Desmume, PCEjin, VBA-rr, PCSX-rr, Yabause, VBjin, and FBA-rr.

+


+


+

It is designed to filter RAM values just like in the Cheat Search dialog.  However, it features many options that are lacking in the Cheat Search dialog.  Among these are search undo, search preview, a modulus filter, a data size option, signed/unsigned/hex options, autosearch, and several more compare by options.

+


+

Documentation on this dialog can be found on TASVideos here.

+


+

Hotkeys

+


+

Hotkeys can be assigned to common search commands so they can be easily selected while in the main window.

+

+

Created with the Personal Edition of HelpNDoc: Free EPub producer

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/RAMWatch.html b/web/help/RAMWatch.html index 948818e6..59b1fe7d 100644 --- a/web/help/RAMWatch.html +++ b/web/help/RAMWatch.html @@ -1,78 +1,269 @@ - - + + + + + - RAM Watch - - - - - - - - - - + + + + + + + + RAM Watch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

RAM Watch

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Ram Watch

-


-

Ram Watch is a tool originally written for GENS rerecording.  It was ported to FCEUX in version 2.1.2.  This dialog has also been ported to SNES9x-rr, Desmume, PCEjin, VBA-rr, PCSX-rr, Yabause, and FBA-rr.

-


-

It is designed to filter ram values just like in the Cheat Search dialog.  However, it features many options that are lacking in the Cheat Search dialog.  Among these are search undo, search preview, a modulus filter, a data size option, signed/unsigned/hex options, autosearch, and several more compare by options.

-


-

Documentation on this dialog can be found on TASVideos here.

-

-

Created with the Personal Edition of HelpNDoc: Free help authoring environment

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

RAM Watch

+ +
+ +

+

Ram Watch

+


+

Ram Watch is a tool originally written for GENS rerecording.  It was ported to FCEUX in version 2.1.2.  This dialog has also been ported to SNES9x-rr, Desmume, PCEjin, VBA-rr, PCSX-rr, Yabause, and FBA-rr.

+


+

It is designed to filter ram values just like in the Cheat Search dialog.  However, it features many options that are lacking in the Cheat Search dialog.  Among these are search undo, search preview, a modulus filter, a data size option, signed/unsigned/hex options, autosearch, and several more compare by options.

+


+

Documentation on this dialog can be found on TASVideos here.

+

+

Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/ROMHacking.html b/web/help/ROMHacking.html index fada4be4..0782de84 100644 --- a/web/help/ROMHacking.html +++ b/web/help/ROMHacking.html @@ -1,98 +1,289 @@ - - + + + + + - ROM Hacking - - - - - - - - - - + + + + + + + + ROM Hacking + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

ROM Hacking

- -
- FAQ / Guides ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

ROM Hacking

-


-

What is ROM Hacking?

-


-

ROM Hacking is the process of modifying a video game ROM image to alter the game's graphics, dialogue, levels, gameplay, or other gameplay elements. This is usually done by technically-inclined video game fans to breathe new life into a cherished old game, as a creative outlet, or to make essentially new unofficial games using an old game as a foundation.

-


-

ROM hacking is generally accomplished through use of a hex editor (a program for editing non-textual data) and various specialized tools such as tile editors, and game-specific tools which are generally used for editing levels, items, and the like, although more advanced tools such as assemblers and debuggers are occasionally used. Once ready, they are usually distributed on the Internet for others to play on an emulator.

-


-

For more information on ROM Hacking:

-

"The ROM Hackers Bible"

-

Parodius - ROM Hacking Community

-

ROM-Hacking.net Archive

-


-


-

FCEUX ROM-Hacking Features

-


-

FCEUX provides a wealth of tools and resources to aid in hacking NES & FDS games.  It features the most current and cutting edge tools debugging and hacking games as well as making the process quicker an easier.

-


-

Debugging / Reverse engineering:

-

Debugger, Trace Logger, Code/Data Logger, Cheat Search, RAM Filter, Movie Making tools/Frame Advance

-


-

Memory & PPU Viewing:

-

Debugger, PPU Viewer, Hex Editor, Trace Logger, Code/Data Logger

-


-

ROM Editing / Game Genie Codes

-

Debugger, Hex Editor, Cheat Search, Game Genie Decoder/Encoder

-


-

-

Created with the Personal Edition of HelpNDoc: Generate EPub eBooks with ease

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

ROM Hacking

+ +
+ +

+

ROM Hacking

+


+

What is ROM Hacking?

+


+

ROM Hacking is the process of modifying a video game ROM image to alter the game's graphics, dialogue, levels, gameplay, or other gameplay elements. This is usually done by technically-inclined video game fans to breathe new life into a cherished old game, as a creative outlet, or to make essentially new unofficial games using an old game as a foundation.

+


+

ROM hacking is generally accomplished through use of a hex editor (a program for editing non-textual data) and various specialized tools such as tile editors, and game-specific tools which are generally used for editing levels, items, and the like, although more advanced tools such as assemblers and debuggers are occasionally used. Once ready, they are usually distributed on the Internet for others to play on an emulator.

+


+

For more information on ROM Hacking:

+

"The ROM Hackers Bible"

+

Parodius - ROM Hacking Community

+

ROM-Hacking.net Archive

+


+


+

FCEUX ROM-Hacking Features

+


+

FCEUX provides a wealth of tools and resources to aid in hacking NES & FDS games.  It features the most current and cutting edge tools debugging and hacking games as well as making the process quicker an easier.

+


+

Debugging / Reverse engineering:

+

Debugger, Trace Logger, Code/Data Logger, Cheat Search, RAM Filter, Movie Making tools/Frame Advance

+


+

Memory & PPU Viewing:

+

Debugger, PPU Viewer, Hex Editor, Trace Logger, Code/Data Logger

+


+

ROM Editing / Game Genie Codes

+

Debugger, Hex Editor, Cheat Search, Game Genie Decoder/Encoder

+


+

+

Created with the Personal Edition of HelpNDoc: What is a Help Authoring tool?

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Sound.html b/web/help/Sound.html index d960ec8a..5715f762 100644 --- a/web/help/Sound.html +++ b/web/help/Sound.html @@ -1,79 +1,270 @@ - - + + + + + - Sound - - - - - - - - - - + + + + + + + + Sound + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Sound

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Sound

-


-

Includes specifications for the NSF Format & NES Sound core

-


-


-

NSF Format

-


-

NES Sound

-

-

Created with the Personal Edition of HelpNDoc: Create iPhone web-based documentation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Sound

+ +
+ +

+

Sound

+


+

Includes specifications for the NSF Format & NES Sound core 

+


+


+

NSF Format

+


+

NES Sound

+

+

Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/SoundOptions.html b/web/help/SoundOptions.html index dfd46d55..4714956a 100644 --- a/web/help/SoundOptions.html +++ b/web/help/SoundOptions.html @@ -1,119 +1,310 @@ - - + + + + + - Sound - - - - - - - - - - + + + + + + + + Sound + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Sound

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Sound Configuration

-


-

where you can configure sound

-


-


-

Input/Output format

-


-

The sound enabled/disabled checkbox will turn on/off FCEUX's sound.

-

The force 8-bit sound checkbox will override the current sound configuration and use 8-bit sound instead.

-


-

You can select the sound quality in the sound quality pull down menu.

-


-

Rate sets the audio sample rate.

-


-


-

Mute frame advance

-


-

If checked, no sound will be produce when frame advance is pressed.

-


-

Mute Turbo

-


-

If checked, the sound processing will be bypassed when emulation is in turbo mode

-


-

Swap Duty Cycles

-


-

If checked, replicates the behavior of some famiclones that have duty cycles swapped for square channels.

-


-

Buffering

-


-

On older machines, increased buffering may be necessary.  If the sound is glitchy or crackling, increasing the buffing time may resolve the issue.  Lower buffering settings can reduce sound latency.

-


-

Volume Control

-


-

Sets the sound volume of the master sound or individual sound channels.

-


-

Master

-


-

Sets the Master volume level.  You can also set volume levels using the sound volume up, volume down, mute, and volume normal hotkeys under map hotkeys menu.

-


-

Triangle/Square 1/Square 2/Noise/PCM

-


-

Sets the volume to each individual sound channel.

-


-

Note: When using low quality sound, the amount of channel control is greatly limited.  Some sound channels are disabled.

-


-

Restore Defaults

-


-

Restores the master and individual sound channel volumes to their default location.

-

-

Created with the Personal Edition of HelpNDoc: Easily create Web Help sites

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Sound

+ +
+ +

+

Sound Configuration

+


+

where you can configure sound

+


+


+

Input/Output format

+


+

The sound enabled/disabled checkbox will turn on/off FCEUX's sound.

+

The force 8-bit sound checkbox will override the current sound configuration and use 8-bit sound instead.

+


+

You can select the sound quality in the sound quality pull down menu.

+


+

Rate sets the audio sample rate.

+


+


+

Mute frame advance

+


+

If checked, no sound will be produce when frame advance is pressed.

+


+

Mute Turbo

+


+

If checked, the sound processing will be bypassed when emulation is in turbo mode

+


+

Swap Duty Cycles

+


+

If checked, replicates the behavior of some famiclones that have duty cycles swapped for square channels.

+


+

Buffering

+


+

On older machines, increased buffering may be necessary.  If the sound is glitchy or crackling, increasing the buffing time may resolve the issue.  Lower buffering settings can reduce sound latency.

+


+

Volume Control

+


+

Sets the sound volume of the master sound or individual sound channels.

+


+

Master

+


+

Sets the Master volume level.  You can also set volume levels using the sound volume up, volume down, mute, and volume normal hotkeys under map hotkeys menu.

+


+

Triangle/Square 1/Square 2/Noise/PCM

+


+

Sets the volume to each individual sound channel.

+


+

Note: When using low quality sound, the amount of channel control is greatly limited.  Some sound channels are disabled.

+


+

Restore Defaults

+


+

Restores the master and individual sound channel volumes to their default location.

+

+

Created with the Personal Edition of HelpNDoc: Produce online help for Qt applications

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/TASEditor.html b/web/help/TASEditor.html index 9e13f3bd..23dc671b 100644 --- a/web/help/TASEditor.html +++ b/web/help/TASEditor.html @@ -1,83 +1,274 @@ - - + + + + + - TAS Editor - - - - - - - - - - + + + + + + + + TAS Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

TAS Editor

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

TAS Editor

-


-


-

TAS Editor is an overhaul in the logic of creating TAS movies (see Tool Assisted Speedruns). It is a powerful new design that takes movie making from a "recording" concept to a "creating an input file" way of thinking.

-


-

In the 2.2.0 release the TAS Editor was completely redesigned and rewritten, incorporating new experimental ideas.

-

Now it also has its own Manual, see taseditor.chm or fceux.com/web/help/taseditor/

-


-

The tool is only available in Windows version of FCEUX.

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

TAS Editor

+ +
+ +

+

TAS Editor

+


+


+

TAS Editor is an overhaul in the logic of creating TAS movies (see Tool Assisted Speedruns). It is a powerful new design that takes movie making from a "recording" concept to a "creating an input file" way of thinking.

+


+

In the 2.2.0 release the TAS Editor was completely redesigned and rewritten, incorporating new experimental ideas.

+

Now it also has its own Manual, see taseditor.chm or fceux.com/web/help/taseditor/

+


+

The tool is only available in Windows version of FCEUX.

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured multi-format Help generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Technicalinformation.html b/web/help/Technicalinformation.html index 785475fe..fa9ff4bd 100644 --- a/web/help/Technicalinformation.html +++ b/web/help/Technicalinformation.html @@ -1,74 +1,269 @@ - - + + + + + - Technical Information - - - - - - - - - - + + + + + + + + Technical Information + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Technical Information

- -
-
- Previous - - Next - -
-
-
-
- -

-

Technical Information

-


-

These chapters deal with documentation of specific hardware configurations of the NES and/or how the FCEU core emulates these aspects.

-


-

More documentation about NES and Famicom hardware specifications can be found at: http://nesdev.parodius.com/

-


-


-

-

Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Technical Information

+ +
+ +

+

Technical Information

+


+

These chapters deal with documentation of specific hardware configurations of the NES and/or how the FCEU core emulates these aspects.

+


+

More documentation about NES and Famicom hardware specifications can be found at: http://nesdev.parodius.com/

+


+


+

+

Created with the Personal Edition of HelpNDoc: Free help authoring environment

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/TextHooker.html b/web/help/TextHooker.html index 9382e58a..b5939031 100644 --- a/web/help/TextHooker.html +++ b/web/help/TextHooker.html @@ -1,167 +1,358 @@ - - + + + + + - Text Hooker - - - - - - - - - - + + + + + + + + Text Hooker + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Text Hooker

- -
- Tools ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Text Hooker

-


-

(written by Ugly Joe, author of the Text Hooker tool)

-


-


-

What is Text Hooker?

-


-

Here's a premise for you. Suppose you've pirated a bunch of Japanese NES roms and you load one of them up at random. Cool music. Cool title screen. You go to start a game, put in ???? at the name entry screen, and get to the actual game. Well, big surprise here, it's an RPG. You soon realize that you have no idea what people are saying, what shops are selling, or what your battle options are. It can be fun to trial-and-error for a while, but you're ultimately stuck in the first town. Time to load up a new ROM.

-


-

Well, being the aspiring Japanophile that I am, I have all kinds of translation tools and websites at my disposal. It's not impossible for me to figure out the kana for an item name, put it into a website somewhere, and figure out what it is. It's a slow process, but I can figure out short, simple strings of Japanese text. Sometimes, this is all I need to know to get by.

-


-

This is why I made the Text Hooker. What it allows you to do is highlight text boxes in the game and copy the kana right to the clipboard. I no longer have to look up stuff, I can just copy from the emulator, paste into the website, and go from there. While developing it, I took it a bit further by adding a (shoddy) translator right into the app, and added features such as word substitutions (so you only have to look up the word once and then the app will know what it is as soon as you copy it). What you end up with is kind of like a translator's notebook. It keeps commonly used words in a dictionary and helps you get through a Japanese game without having too much knowledge of the Japanese language.

-


-


-

What do I need to use to use it?

-


-

Some knowledge of the Japanese language

-

I really can't say how much you need to know, but I suppose the more you know the better. I could be wrong, but I think you need to know at least something about the language before you can start copy/pasting translations.

-


-

Know how to make a Japanese table file

-

I'm not going to explain how to do this since there are adequate tutorials already out there. You'll need to be able to do this per game in order for the Text Hooker to work.

-


-

Japanese font support

-

Okay, I have tested this thing on a Win98 installation with no Japanese font. It still works. However, I didn't test it for very long and I'm not sure how well translation websites are going to work without it. So, it might work without Japanese font support, but I'm not officially saying it does.

-


-

A Japanese ROM

-

Duh, you'll need a game to play. Find it yourself.

-


-


-

How do I use the Text Hooker?

-


-

First of all, you need to make your table file. The text hooker doesn't use Thingy tables, but uses a modified Thingy table instead. So, make your standard Thingy table file, but save it with a .tht extension (instead of .tbl). What you need to add to the table are the dakuten and handakuten marks (tenten and maru). The byte for the dakuten mark needs to be set to tenten and the byte for the handakuten mark needs to be set to tenten. Like:

-


-

DC=tenten

-

DD=maru

-


-

If you don't do this, the Text Hooker will fail miserabley when copying the text over from the game.

-


-

Once you have your table file ready, open up your rom in FCEUXDSP CE and open the text hooker window (Tools -> Text Hooker). Click on the "Load Table" button and open up your .tht file. Now you can really get ready to work.

-


-

Basic Usage

-


-

A warning

-

All information is saved in the table file. You have to save your table manually using the Save Table button. If you close the Text Hooker window or load a different table, your changes since the last save will be lost. You will not be prompted to save changes. Please remember to save!

-


-

Making Selections

-

The Selection Window is where you select the text in the game. It is basically the same view as the actual emulator window, but it updates less often and does not show sprites (text is not drawn with sprites, so they are not needed). To make a selection, click on a deselected tile and drag your mouse. To remove a selection, click on a selected tile and drag your mouse. It works a lot like a pen tool and an eraser tool in standard paint programs.

-


-

Once you have made a selection, you can save it for later use. This comes in handy since most RPGs will display their text boxes and battle menus in the same place throughout the entire game. To save a selection, type a name for the selection into the New Selection Name field and press the Save Selection button. Note that this selection will not be saved to your table file until you press the Save Table button.

-


-

You can also use the Clear Selection button to deselect all of the tiles in the selection window.

-


-

Please note that when you select text, you should not select the mostly blank rows that contains the dakuten and handakuten marks. You're essentially selecting every other row. Please see the UI image above for an example.

-


-

Translating Text

-

Once you've made a selection, press the big Snap button to copy the text into the Hooked Text window. Only the tiles that are defined in your table file will be copied over. All other tiles will be ignored. Once you have some Japanese text in your Hooked Text window, you have a few options. You can press the Excite.co.jp button to receive a really bad translation (better than Babelfish, but still bad) in the Translated Text window, or you can select all or part of the text in the Hooked Text window and copy/paste it into another translation tool or website. If you're translating a block of text (as opposed to item names or menus), you should probably use the Trim button to clean up the excess whitespace.

-


-

Please bear in mind that, due to the limitations of the NES, Japenese games use very little kanji. This means you'll have to look up the kana representation of what would normally be a kanji. Most translation tools will give you a hard time about this.

-


-

The word substitution feature can be used to process the selected text before it is sent to the Hooked Text window. By entering in Japanese-to-English definitions, you build up your word subs dictionary. If word subs are enabled and you press the snap button, the selected text is checked against your dictionary and any words that it finds are replaced by their definition.

-


-

This is useful for a few reason. One, many words written in katakana don't translate too well. You can use this to stop the translators from mangling them. Two, character names are often the same thing as words. For example, if your character's name is ??? (Sakura), the translator will likely translate it to “cherry blossom”. If you define ??? as Sakura, then you won't have to worry about that. Three, you only really need to translate menus and items once. Once you have them figured out, add them to your dictionary. This way, you can just select your menu (perhaps from a saved selection?) and press Snap -- instant menu translation! Four, I'm not positive about this, but if you know that a string of kana is going to always mean a particular kanji, you could put the kana in the Japanese side and the kanji in the English side. This would aid translators since it wouldn't have to try and figure it out itself. Note that I haven't tested that last one since I don't know enough kanji to put it to the test.

-


-

Again, please remember that your dictionary will not be saved unless you use the Save Table button.

-


-

Tweaking

-

Here are some other helpful features.

-


-

Pause Button: this is used to pause and unpause the emulator.

-


-

Scanline: this is used to determine on what scanline the Selection Window will be updated. Some games will switch their font tiles in and out of the PPU. If this happens, you may need to change the scanline to a bigger number in order to see the tiles you're looking for. For example, this happens a lot in the game Metal Slader Glory.

-


-

Update every x frames: this is used to determine how often the Selection Window is updated. The smaller the number, the slower the emulator will go.

-


-

Selection Window checkbox: this is used to determine whether or not the selection window should be updated. If you're not going to be needing the Text Hooker for a while, you should probably uncheck this box while you play.

-


-

Word Substitution checkbox: this is used to determine whether or not word substitution will be used.

-


-

(han)dakuten mark position checkbox: this is used to tell the text hooker where the dakuten and handakuten marks are located in relation to the kana. Most games will use Above, but some games that try to squeeze in as much text into a small area as possible will use Right.

-

Features > Text Hooker > Reference

-

Features > Text Hooker > Reference > Text Hooker Table file reference

-

I suppose this is the kind of thing that should be documented, so here it is. When I started to make this thing, I was just using Thingy tables. When I started to add other features, I knew I needed to save them somewhere. It seemed kind of dumb to me to store this information in separate files, so I decided I would append the other sections to the end of the table files. In the far off chance that there becomes some kind of archive for Text Hooker table files, I decided to use a different extension.

-


-

A .tht file is comprised of three parts (and possibly more in the future). The first part resembles a Thingy table, since it's more or less that same thing. You have a hex byte value, and equals sign, and the corresponding character after the equals sign. The biggest difference from Thingy tables is that the tenten and maru marks must be defined using the words tenten and maru.

-


-

The next section is the Selections storage. This section begins with a

-


-

[selections]

-


-

declaration. What follows are hashes for saved selections (name of selection, equals sign, hash). The hashes should be safe for viewing and saving in any text editor that is capable of viewing and saving Japanese text. These hashes are, admittedly, under tested. If anyone can find a situation in which the selection hashes are corrupted but the rest of the table file is not, please let me know.

-


-

Up next is the Word Substitution Dictionary. This section begins with a

-


-

[words]

-


-

declaration. These lines are formatted in a Japanese=English manner. You should be able to have Japanese or English on either or both sides. It's nothing more than a list of values used during a search and replace function.

-

-

Created with the Personal Edition of HelpNDoc: Easy EPub and documentation editor

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Text Hooker

+ +
+ +

+

Text Hooker

+


+

(written by Ugly Joe, author of the Text Hooker tool)

+


+


+

What is Text Hooker? 

+


+

Here's a premise for you. Suppose you've pirated a bunch of Japanese NES roms and you load one of them up at random. Cool music. Cool title screen. You go to start a game, put in ???? at the name entry screen, and get to the actual game. Well, big surprise here, it's an RPG. You soon realize that you have no idea what people are saying, what shops are selling, or what your battle options are. It can be fun to trial-and-error for a while, but you're ultimately stuck in the first town. Time to load up a new ROM.

+


+

Well, being the aspiring Japanophile that I am, I have all kinds of translation tools and websites at my disposal. It's not impossible for me to figure out the kana for an item name, put it into a website somewhere, and figure out what it is. It's a slow process, but I can figure out short, simple strings of Japanese text. Sometimes, this is all I need to know to get by.

+


+

This is why I made the Text Hooker. What it allows you to do is highlight text boxes in the game and copy the kana right to the clipboard. I no longer have to look up stuff, I can just copy from the emulator, paste into the website, and go from there. While developing it, I took it a bit further by adding a (shoddy) translator right into the app, and added features such as word substitutions (so you only have to look up the word once and then the app will know what it is as soon as you copy it). What you end up with is kind of like a translator's notebook. It keeps commonly used words in a dictionary and helps you get through a Japanese game without having too much knowledge of the Japanese language.

+


+


+

What do I need to use to use it?

+


+

Some knowledge of the Japanese language

+

I really can't say how much you need to know, but I suppose the more you know the better. I could be wrong, but I think you need to know at least something about the language before you can start copy/pasting translations.

+


+

Know how to make a Japanese table file

+

I'm not going to explain how to do this since there are adequate tutorials already out there. You'll need to be able to do this per game in order for the Text Hooker to work.

+


+

Japanese font support

+

Okay, I have tested this thing on a Win98 installation with no Japanese font. It still works. However, I didn't test it for very long and I'm not sure how well translation websites are going to work without it. So, it might work without Japanese font support, but I'm not officially saying it does.

+


+

A Japanese ROM

+

Duh, you'll need a game to play. Find it yourself.

+


+


+

How do I use the Text Hooker?

+


+

First of all, you need to make your table file. The text hooker doesn't use Thingy tables, but uses a modified Thingy table instead. So, make your standard Thingy table file, but save it with a .tht extension (instead of .tbl). What you need to add to the table are the dakuten and handakuten marks (tenten and maru). The byte for the dakuten mark needs to be set to tenten and the byte for the handakuten mark needs to be set to tenten. Like:

+


+

DC=tenten

+

DD=maru

+


+

If you don't do this, the Text Hooker will fail miserabley when copying the text over from the game.

+


+

Once you have your table file ready, open up your rom in FCEUXDSP CE and open the text hooker window (Tools -> Text Hooker). Click on the "Load Table" button and open up your .tht file. Now you can really get ready to work.

+


+

Basic Usage

+


+

A warning

+

All information is saved in the table file. You have to save your table manually using the Save Table button. If you close the Text Hooker window or load a different table, your changes since the last save will be lost. You will not be prompted to save changes. Please remember to save!

+


+

Making Selections

+

The Selection Window is where you select the text in the game. It is basically the same view as the actual emulator window, but it updates less often and does not show sprites (text is not drawn with sprites, so they are not needed). To make a selection, click on a deselected tile and drag your mouse. To remove a selection, click on a selected tile and drag your mouse. It works a lot like a pen tool and an eraser tool in standard paint programs.

+


+

Once you have made a selection, you can save it for later use. This comes in handy since most RPGs will display their text boxes and battle menus in the same place throughout the entire game. To save a selection, type a name for the selection into the New Selection Name field and press the Save Selection button. Note that this selection will not be saved to your table file until you press the Save Table button.

+


+

You can also use the Clear Selection button to deselect all of the tiles in the selection window.

+


+

Please note that when you select text, you should not select the mostly blank rows that contains the dakuten and handakuten marks. You're essentially selecting every other row. Please see the UI image above for an example.

+


+

Translating Text

+

Once you've made a selection, press the big Snap button to copy the text into the Hooked Text window. Only the tiles that are defined in your table file will be copied over. All other tiles will be ignored. Once you have some Japanese text in your Hooked Text window, you have a few options. You can press the Excite.co.jp button to receive a really bad translation (better than Babelfish, but still bad) in the Translated Text window, or you can select all or part of the text in the Hooked Text window and copy/paste it into another translation tool or website. If you're translating a block of text (as opposed to item names or menus), you should probably use the Trim button to clean up the excess whitespace.

+


+

Please bear in mind that, due to the limitations of the NES, Japenese games use very little kanji. This means you'll have to look up the kana representation of what would normally be a kanji. Most translation tools will give you a hard time about this.

+


+

The word substitution feature can be used to process the selected text before it is sent to the Hooked Text window. By entering in Japanese-to-English definitions, you build up your word subs dictionary. If word subs are enabled and you press the snap button, the selected text is checked against your dictionary and any words that it finds are replaced by their definition.

+


+

This is useful for a few reason. One, many words written in katakana don't translate too well. You can use this to stop the translators from mangling them. Two, character names are often the same thing as words. For example, if your character's name is ??? (Sakura), the translator will likely translate it to “cherry blossom”. If you define ??? as Sakura, then you won't have to worry about that. Three, you only really need to translate menus and items once. Once you have them figured out, add them to your dictionary. This way, you can just select your menu (perhaps from a saved selection?) and press Snap -- instant menu translation! Four, I'm not positive about this, but if you know that a string of kana is going to always mean a particular kanji, you could put the kana in the Japanese side and the kanji in the English side. This would aid translators since it wouldn't have to try and figure it out itself. Note that I haven't tested that last one since I don't know enough kanji to put it to the test.

+


+

Again, please remember that your dictionary will not be saved unless you use the Save Table button.

+


+

Tweaking

+

Here are some other helpful features.

+


+

Pause Button: this is used to pause and unpause the emulator.

+


+

Scanline: this is used to determine on what scanline the Selection Window will be updated. Some games will switch their font tiles in and out of the PPU. If this happens, you may need to change the scanline to a bigger number in order to see the tiles you're looking for. For example, this happens a lot in the game Metal Slader Glory.

+


+

Update every x frames: this is used to determine how often the Selection Window is updated. The smaller the number, the slower the emulator will go.

+


+

Selection Window checkbox: this is used to determine whether or not the selection window should be updated. If you're not going to be needing the Text Hooker for a while, you should probably uncheck this box while you play.

+


+

Word Substitution checkbox: this is used to determine whether or not word substitution will be used.

+


+

(han)dakuten mark position checkbox: this is used to tell the text hooker where the dakuten and handakuten marks are located in relation to the kana. Most games will use Above, but some games that try to squeeze in as much text into a small area as possible will use Right.

+

Features > Text Hooker > Reference

+

Features > Text Hooker > Reference > Text Hooker Table file reference

+

I suppose this is the kind of thing that should be documented, so here it is. When I started to make this thing, I was just using Thingy tables. When I started to add other features, I knew I needed to save them somewhere. It seemed kind of dumb to me to store this information in separate files, so I decided I would append the other sections to the end of the table files. In the far off chance that there becomes some kind of archive for Text Hooker table files, I decided to use a different extension.

+


+

A .tht file is comprised of three parts (and possibly more in the future). The first part resembles a Thingy table, since it's more or less that same thing. You have a hex byte value, and equals sign, and the corresponding character after the equals sign. The biggest difference from Thingy tables is that the tenten and maru marks must be defined using the words tenten and maru.

+


+

The next section is the Selections storage. This section begins with a

+


+

[selections]

+


+

declaration. What follows are hashes for saved selections (name of selection, equals sign, hash). The hashes should be safe for viewing and saving in any text editor that is capable of viewing and saving Japanese text. These hashes are, admittedly, under tested. If anyone can find a situation in which the selection hashes are corrupted but the rest of the table file is not, please let me know.

+


+

Up next is the Word Substitution Dictionary. This section begins with a

+


+

[words]

+


+

declaration. These lines are formatted in a Japanese=English manner. You should be able to have Japanese or English on either or both sides. It's nothing more than a list of values used during a search and replace function. 

+

+

Created with the Personal Edition of HelpNDoc: Free EPub and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Timing.html b/web/help/Timing.html index d0b9a2f1..ece71052 100644 --- a/web/help/Timing.html +++ b/web/help/Timing.html @@ -1,93 +1,284 @@ - - + + + + + - Timing - - - - - - - - - - + + + + + + + + Timing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Timing

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Timings

-


-

Settings related to emulation timing.

-


-


-

Disable Speed Throttling Used When Sound is Disabled

-


-

If checked, speed throttling will not be used while sound is disabled.  (Speed throttling gives a performance boost while sound is off).

-


-

Set High Priority Thread

-


-

Sets processing priority.  Enabling can help slower computers keep a steady 60fps (or 50fps) framerate.

-


-

Overclocking (old PPU only)

-


-

Overclocks the console by adding dummy scanlines to the usual PPU loop, causing CPU to run more cycles per frame. Can be done in two different ways: by adding Post-render scanlines and by adding Vblank scanlines. The method to be used depends on the game. Maximum value is 999.

-


-

Don't overclock 7-bit samples

-


-

Such samples are played by the game at the rate it wants, so by running extra cycles, it will generate extra samples. To prevent those from being sped up, this option allows to cancel all the dummy scanlines once a 7-bit sample starts. This hardly affects gameplay, since such samples cause heavy lag, preventing the game from actually operating, so disabling overclocking during them won't slow the game down.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Timing

+ +
+ +

+

Timings

+


+

Settings related to emulation timing.

+


+


+

Disable Speed Throttling Used When Sound is Disabled

+


+

If checked, speed throttling will not be used while sound is disabled.  (Speed throttling gives a performance boost while sound is off).

+


+

Set High Priority Thread

+


+

Sets processing priority.  Enabling can help slower computers keep a steady 60fps (or 50fps) framerate.

+


+

Overclocking (old PPU only)

+


+

Overclocks the console by adding dummy scanlines to the usual PPU loop, causing CPU to run more cycles per frame. Can be done in two different ways: by adding Post-render scanlines and by adding Vblank scanlines. The method to be used depends on the game. Maximum value is 999.

+


+

Don't overclock 7-bit samples

+


+

Such samples are played by the game at the rate it wants, so by running extra cycles, it will generate extra samples. To prevent those from being sped up, this option allows to cancel all the dummy scanlines once a 7-bit sample starts. This hardly affects gameplay, since such samples cause heavy lag, preventing the game from actually operating, so disabling overclocking during them won't slow the game down.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Free EBook and documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/ToggleSwitchesHideMenuetc.html b/web/help/ToggleSwitchesHideMenuetc.html index 1aaa5d23..69ab6dbb 100644 --- a/web/help/ToggleSwitchesHideMenuetc.html +++ b/web/help/ToggleSwitchesHideMenuetc.html @@ -1,205 +1,396 @@ - - + + + + + - Menu Items & Submenus - - - - - - - - - - + + + + + + + + Menu Items & Submenus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Menu Items & Submenus

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Config Toggle Switches

-


-

Explains the various toggle switch commands in the top two groups of commands under the Config Menu.

-


-


-

Hide Menu

-


-

Hides the Menu commands on the FCEUX main window.  Press ESC to unhide the menu.

-


-


-

Region

-


-

Allows to choose between NTSC (224p@60fps), PAL and Dendy (240p@50fps) modes. For PAL, FCEUX will detect the proper choice when loading a ROM and set the flag accordingly (based on file name, where (E) is used by GoodTools to mark European ROMs). Dendy mode (sometimes also called Hybrid) is a modification of the NTSC one, it was used in some Famiclones and supports games released for the NTSC region, slowing them down to PAL speed.

-

Note: you can't change this setting while a movie is being played or recorded.

-


-


-

PPU (Sub-menu)

-


-

New PPU / Old PPU

-

As of FCEUX 2.1.2, FCEUX has a new PPU core.  The new PPU has improved accuracy and greater game compatibility than the old PPU.  However, some games may not work properly and there will be slight timing differences that would hurt movie compatibility. Also then New PPU is much slower than the Old PPU. Therefore, the old PPU is still the preferred setting.

-

Note: you can't change this setting while a movie is being played or recorded.

-


-


-

Enable (Sub-menu)

-


-

Run in Background

-


-

If enabled, FCEUX will continue to emulate when the window is not in focus.  If disabled, the emulator will pause when out of focus.

-


-


-

Background Input

-


-

If enabled, FCEUX can continue to receive input while not in focus.  (Useful for playing 2 FCEUX's simultaneously)

-


-


-

Auto-savestates

-


-

Enables the Auto-save feature.  If enabled, FCEUX will make periodic savestates (once per every 256 frames) as you play or record a movie.  You can right-click and select the "load last auto-save" in the context menu or press "Load Last Auto-save" hotkey to back up to the last auto-save savestate.

-


-


-

Frame Adv. - Skip Lag

-


-

This feature, if enabled, will cause the frame advance key (see movie recording) to skip over lag frames.  It does this by reading the lag counter and skipping past any frames where input is not polled.  

-


-

For instance, in a 30fps game (such as double dragon), frame advance will advance 2 frames instead of 1.

-


-


-

Backup Savestates

-


-

Enabled by default.  This option allows for savestate & loadstate Undo (& redo).  (see context menu)

-


-


-

Compress Savestates

-


-

Enabled by default.  This option compresses non movie savestates.

-


-


-

Game Genie ROM

-


-

Allows the use of the game genie ROM.  You must have a game genie ROM named gg.rom (it is safe to rename a game genie.nes file to gg.rom) and it must be in the FCEUX base directory (which is the folder fceux.exe is in unless you specified a different folder in the Directory Override Menu).

-


-

If enabled, FCEUX will open gg.rom first when you load a new game.  Any codes applied in the game genie screen will be applied to the game just like on a real NES.  

-


-

(Remember that enabling/disabling Game Genie emulation will not take effect until a new game is loaded)

-


-

Note:  Game genie codes can also be added with the Game Genie Encoder/Decoder via the Cheat Search Menu (and this method does not require a game genie ROM).

-


-


-

Auto-resume old play session

-


-

If enabled, FCEUX will make a special savestate every time you close ROM, and will automatically load the savestate when you open this ROM next time, so you can continue from where you left the game. In addition, when this option is enabled, FCEUX automatically loads the last used ROM on startup.

-


-


-

Display (Sub-Menu)

-


-

Input Display

-


-

The input display will display 1-4 pictures of a NES controller at the bottom of the screen.  When playing/recording a movie, these controllers will display the input that is captured in the file.  

-


-

When input comes from a movie file rather than then user, it is displayed in a different color (silver)

-


-

The input display can also be toggled by hotkey.  The default key for toggling the Input display is the "," (comma) key.  (This can be re-mapped in the Map Hotkeys Menu).

-


-


-

Lag Counter

-


-

The lag counter will increment every time to the game fails to poll for user input.  It will display in red on any frame that is currently lagging and will increment the lag counter by 1.  These situations occur when the game is lagging (too much information to process), or the game is in a screen transition state (so not polling for user input).  In  a 30fps game (such as Double Dragon 2), it will increment every other frame.

-


-

The lag counter value is stored in savestates.    

-


-

Displaying the lag counter can also be toggled by hotkey.  The default key is the "/" (slash) key.  (This can be re-mapped in the Map Hokeys Menu).

-


-


-

Frame Counter

-


-

Toggles the display of the frame counter.  The frame counter will increment once per frame.

-


-

The frame counter display can also be toggled by hotkey.  The default key is the "." (period) key.  (This can be re-mapped in the Map Hotkeys Menu).

-


-


-

Rerecord Counter

-


-

Toggles the display of the number of Rerecords done when making a movie.  The Rerecord counter will increment every time you load a savestate in Recording mode.

-


-

The rerecord counter display can also be toggled by hotkey.  The default key is the "M" key.  (This can be re-mapped in the Map Hotkeys Menu).

-


-


-

Movie status icon

-


-

Toggles the display of "pause", "play" or "record" icons in the lower right corner.

-


-


-

FPS

-


-

Toggles the display of average FPS counter in the upper right corner.

-


-


-

Graphics: BG

-


-

Turning this off will turn off the backgrounds in the game.

-


-


-

Graphics: OBJ

-


-

Turning this off will turn off the objects (sprites) in the game.

-


-

Note: You can set the default color when the Backgrounds are turned off.  To do so, open fceux.cfg and change the value of the entry named: gNoBGFillColor

-


-


-

Save Config File

-


-

Saves current settings to fceux.cfg.  Normally settings are not saved until FCEUX is closed.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Free iPhone documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Menu Items & Submenus

+ +
+ +

+

Config Toggle Switches

+


+

Explains the various toggle switch commands in the top two groups of commands under the Config Menu.

+


+


+

Hide Menu

+


+

Hides the Menu commands on the FCEUX main window.  Press ESC to unhide the menu.

+


+


+

Region

+


+

Allows to choose between NTSC (224p@60fps), PAL and Dendy (240p@50fps) modes. For PAL, FCEUX will detect the proper choice when loading a ROM and set the flag accordingly (based on file name, where (E) is used by GoodTools to mark European ROMs). Dendy mode (sometimes also called Hybrid) is a modification of the NTSC one, it was used in some Famiclones and supports games released for the NTSC region, slowing them down to PAL speed.

+

Note: you can't change this setting while a movie is being played or recorded.

+


+


+

PPU (Sub-menu)

+


+

New PPU / Old PPU

+

As of FCEUX 2.1.2, FCEUX has a new PPU core.  The new PPU has improved accuracy and greater game compatibility than the old PPU.  However, some games may not work properly and there will be slight timing differences that would hurt movie compatibility. Also then New PPU is much slower than the Old PPU. Therefore, the old PPU is still the preferred setting.

+

Note: you can't change this setting while a movie is being played or recorded.

+


+


+

Enable (Sub-menu)

+


+

Run in Background

+


+

If enabled, FCEUX will continue to emulate when the window is not in focus.  If disabled, the emulator will pause when out of focus.

+


+


+

Background Input

+


+

If enabled, FCEUX can continue to receive input while not in focus.  (Useful for playing 2 FCEUX's simultaneously)

+


+


+

Auto-savestates

+


+

Enables the Auto-save feature.  If enabled, FCEUX will make periodic savestates (once per every 256 frames) as you play or record a movie.  You can right-click and select the "load last auto-save" in the context menu or press "Load Last Auto-save" hotkey to back up to the last auto-save savestate.

+


+


+

Frame Adv. - Skip Lag

+


+

This feature, if enabled, will cause the frame advance key (see movie recording) to skip over lag frames.  It does this by reading the lag counter and skipping past any frames where input is not polled.  

+


+

For instance, in a 30fps game (such as double dragon), frame advance will advance 2 frames instead of 1.

+


+


+

Backup Savestates

+


+

Enabled by default.  This option allows for savestate & loadstate Undo (& redo).  (see context menu)

+


+


+

Compress Savestates

+


+

Enabled by default.  This option compresses non movie savestates.

+


+


+

Game Genie ROM

+


+

Allows the use of the game genie ROM.  You must have a game genie ROM named gg.rom (it is safe to rename a game genie.nes file to gg.rom) and it must be in the FCEUX base directory (which is the folder fceux.exe is in unless you specified a different folder in the Directory Override Menu).

+


+

If enabled, FCEUX will open gg.rom first when you load a new game.  Any codes applied in the game genie screen will be applied to the game just like on a real NES.  

+


+

(Remember that enabling/disabling Game Genie emulation will not take effect until a new game is loaded)

+


+

Note:  Game genie codes can also be added with the Game Genie Encoder/Decoder via the Cheat Search Menu (and this method does not require a game genie ROM).

+


+


+

Auto-resume old play session

+


+

If enabled, FCEUX will make a special savestate every time you close ROM, and will automatically load the savestate when you open this ROM next time, so you can continue from where you left the game. In addition, when this option is enabled, FCEUX automatically loads the last used ROM on startup.

+


+


+

Display (Sub-Menu)

+


+

Input Display

+


+

The input display will display 1-4 pictures of a NES controller at the bottom of the screen.  When playing/recording a movie, these controllers will display the input that is captured in the file.  

+


+

When input comes from a movie file rather than then user, it is displayed in a different color (silver)

+


+

The input display can also be toggled by hotkey.  The default key for toggling the Input display is the "," (comma) key.  (This can be re-mapped in the Map Hotkeys Menu).

+


+


+

Lag Counter

+


+

The lag counter will increment every time to the game fails to poll for user input.  It will display in red on any frame that is currently lagging and will increment the lag counter by 1.  These situations occur when the game is lagging (too much information to process), or the game is in a screen transition state (so not polling for user input).  In  a 30fps game (such as Double Dragon 2), it will increment every other frame.

+


+

The lag counter value is stored in savestates.    

+


+

Displaying the lag counter can also be toggled by hotkey.  The default key is the "/" (slash) key.  (This can be re-mapped in the Map Hokeys Menu).

+


+


+

Frame Counter

+


+

Toggles the display of the frame counter.  The frame counter will increment once per frame.

+


+

The frame counter display can also be toggled by hotkey.  The default key is the "." (period) key.  (This can be re-mapped in the Map Hotkeys Menu).

+


+


+

Rerecord Counter

+


+

Toggles the display of the number of Rerecords done when making a movie.  The Rerecord counter will increment every time you load a savestate in Recording mode.

+


+

The rerecord counter display can also be toggled by hotkey.  The default key is the "M" key.  (This can be re-mapped in the Map Hotkeys Menu).

+


+


+

Movie status icon

+


+

Toggles the display of "pause", "play" or "record" icons in the lower right corner.

+


+


+

FPS

+


+

Toggles the display of average FPS counter in the upper right corner.

+


+


+

Graphics: BG

+


+

Turning this off will turn off the backgrounds in the game.

+


+


+

Graphics: OBJ

+


+

Turning this off will turn off the objects (sprites) in the game.

+


+

Note: You can set the default color when the Backgrounds are turned off.  To do so, open fceux.cfg and change the value of the entry named: gNoBGFillColor 

+


+


+

Save Config File

+


+

Saves current settings to fceux.cfg.  Normally settings are not saved until FCEUX is closed.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured Help generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/ToolAssistedSpeedruns.html b/web/help/ToolAssistedSpeedruns.html index 20e50935..a3099cbb 100644 --- a/web/help/ToolAssistedSpeedruns.html +++ b/web/help/ToolAssistedSpeedruns.html @@ -1,127 +1,318 @@ - - + + + + + - Tool Assisted Speedruns - - - - - - - - - - + + + + + + + + Tool Assisted Speedruns + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Tool Assisted Speedruns

- -
- FAQ / Guides ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Tool Assisted Speedruns

-


-

What is Tool Assisted Speedrunning?

-


-

A tool-assisted speedrun (commonly abbreviated TAS) is a speedrun movie or performance produced with the use of tools such as slow motion and re-recording. The basic premise of these runs is that a "tool" (such as an emulator that provides the author with features that are unavailable in regular playing) is used in order to overcome human limitations such as skill and reflex.

-


-

Creating a tool-assisted speed run is the process of finding the ideal set of inputs to complete a given criterion - usually completing a game as fast as possible. No limits are imposed on the tools used for this search, but the result has to be a set of timed key-presses that, when played back on the actual console, achieves the target criterion. Traditionally, the only available tool for this was an emulator with re-recording - the ability to use savestate while recording key-presses. However, due to advances in the field, it is now often expected that frame-advance, stepping through emulation one frame at a time, is used. A tool-assisted speed run done without this technique may be criticised as "sloppy play". Before Frame Advance became common, playing in slow motion was a common technique, but Frame Advance has displaced this.

-


-

In essence, Tool Assistance allows one to overcome human limitations of skill and reflex in order to push a game to its limits.  One important thing to remember is that TAS movies are not competing in terms of playing skill, nor do they claim to.

-


-

For more info on Tool Assisted Speedruns:

-

http://tasvideos.org/

-

http://tasvideos.org/WhyAndHow.html

-

http://en.wikipedia.org/wiki/Tool-assisted_speedrun

-


-

FCEUX TAS features

-


-

FCEUX provides a wealth of tools and resources for creating TAS Movies for NES & FDS games.  It features the most current and cutting edge tools for optimizing movies and making the process of movie making quicker an easier.

-


-

Basic Recording features:

-

Frame advance, Slow-downs, "bullet-proof" rerecording, TAS Editor

-


-

Advanced Recording features

-

Input presets, Auto Hold & Auto-Fire

-


-

Automated Movie Making Processes

-

Macros &  Multi-tracking, Lua scripting, Basic Bot,

-


-

Finding RAM values:

-

Cheat Search, RAM Filter, Hex Editor, Debugger, NES RAM Guide

-


-

RAM Monitoring:

-

Memory Watch, Hex Editor

-


-

Movie Splicing Editing

-

Text based file format

-


-

Integrated development system

-

TAS Editor

-


-


-

Movie making

-


-

To get started making a Tool Assisted Movie, simply begin recording a movie (see Movie Recording).  The basic premise of TASing, however, is to use re-records to optimize the execution of a decided upon goal (usually to complete the game as fast as possible).  Re-recording is the act of replacing an already recorded part (of a movie) with something else; also called undo.

-


-

In the making of emulator movies, re-recording is done by loading a savestate of earlier event in the movie and continuing playing from that point.  The emulator will update the movie file to undo everything that was cancelled by the savestate loading, and continue recording from that point.  The makers of tool-assisted speedruns use re-recording very extensively to reach perfection and to avoid mistakes.

-

       * In single-segment non-assisted speedruns, re-recording is starting over from beginning. The recording of the failed playing is usually not preserved.    

-

       * In multi-segment non-assisted speedruns, re-recording is starting over from the beginning of current segment. The recording of the failed segment is not preserved.    

-

       * In tool-assisted speedruns, re-recording only undoes a small part of playing. The undone part will not be seen in the resulting movie.  A tool-assisted movie may have been re-recorded anything between 50 and 200000 times, depending on the precision of the movie and the difficulty of the game.  Often, the same small passage of the game (could be as small as fractions of second long) is attempted tens of times before continuing.

-


-

For more info on making TAS movies:

-

http://tasvideos.org/CommonTricks.html

-

http://tasvideos.org/GenericTips.html

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Tool Assisted Speedruns

+ +
+ +

+

Tool Assisted Speedruns

+


+

What is Tool Assisted Speedrunning?

+


+

A tool-assisted speedrun (commonly abbreviated TAS) is a speedrun movie or performance produced with the use of tools such as slow motion and re-recording. The basic premise of these runs is that a "tool" (such as an emulator that provides the author with features that are unavailable in regular playing) is used in order to overcome human limitations such as skill and reflex.

+


+

Creating a tool-assisted speed run is the process of finding the ideal set of inputs to complete a given criterion - usually completing a game as fast as possible. No limits are imposed on the tools used for this search, but the result has to be a set of timed key-presses that, when played back on the actual console, achieves the target criterion. Traditionally, the only available tool for this was an emulator with re-recording - the ability to use savestate while recording key-presses. However, due to advances in the field, it is now often expected that frame-advance, stepping through emulation one frame at a time, is used. A tool-assisted speed run done without this technique may be criticised as "sloppy play". Before Frame Advance became common, playing in slow motion was a common technique, but Frame Advance has displaced this.

+


+

In essence, Tool Assistance allows one to overcome human limitations of skill and reflex in order to push a game to its limits.  One important thing to remember is that TAS movies are not competing in terms of playing skill, nor do they claim to. 

+


+

For more info on Tool Assisted Speedruns:

+

http://tasvideos.org/

+

http://tasvideos.org/WhyAndHow.html

+

http://en.wikipedia.org/wiki/Tool-assisted_speedrun

+


+

FCEUX TAS features

+


+

FCEUX provides a wealth of tools and resources for creating TAS Movies for NES & FDS games.  It features the most current and cutting edge tools for optimizing movies and making the process of movie making quicker an easier.

+


+

Basic Recording features:

+

Frame advance, Slow-downs, "bullet-proof" rerecording, TAS Editor

+


+

Advanced Recording features 

+

Input presets, Auto Hold & Auto-Fire

+


+

Automated Movie Making Processes

+

Macros &  Multi-tracking, Lua scripting, Basic Bot

+


+

Finding RAM values:

+

Cheat Search, RAM Filter, Hex Editor, Debugger, NES RAM Guide

+


+

RAM Monitoring:

+

Memory Watch, Hex Editor

+


+

Movie Splicing Editing

+

Text based file format

+


+

Integrated development system

+

TAS Editor

+


+


+

Movie making

+


+

To get started making a Tool Assisted Movie, simply begin recording a movie (see Movie Recording).  The basic premise of TASing, however, is to use re-records to optimize the execution of a decided upon goal (usually to complete the game as fast as possible).  Re-recording is the act of replacing an already recorded part (of a movie) with something else; also called undo.

+


+

In the making of emulator movies, re-recording is done by loading a savestate of earlier event in the movie and continuing playing from that point.  The emulator will update the movie file to undo everything that was cancelled by the savestate loading, and continue recording from that point.  The makers of tool-assisted speedruns use re-recording very extensively to reach perfection and to avoid mistakes.

+

       * In single-segment non-assisted speedruns, re-recording is starting over from beginning. The recording of the failed playing is usually not preserved.    

+

       * In multi-segment non-assisted speedruns, re-recording is starting over from the beginning of current segment. The recording of the failed segment is not preserved.    

+

       * In tool-assisted speedruns, re-recording only undoes a small part of playing. The undone part will not be seen in the resulting movie.  A tool-assisted movie may have been re-recorded anything between 50 and 200000 times, depending on the precision of the movie and the difficulty of the game.  Often, the same small passage of the game (could be as small as fractions of second long) is attempted tens of times before continuing. 

+


+

For more info on making TAS movies:

+

http://tasvideos.org/CommonTricks.html

+

http://tasvideos.org/GenericTips.html

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free PDF documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Tools2.html b/web/help/Tools2.html index b454c213..f9bff30c 100644 --- a/web/help/Tools2.html +++ b/web/help/Tools2.html @@ -1,108 +1,303 @@ - - + + + + + - Tools - - - - - - - - - - + + + + + + + + Tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Tools

- -
-
- Previous - - Next - -
-
-
-
- -

-

Tools

-


-


-

Guides for the specific tools and settings under FCEUX's Tools menu.

-


-


-

Cheat Search

-


-

A guide to using the cheat search tool.

-


-


-

Memory Watch

-


-

A guide to using the Memory Watch tool.

-


-


-

RAM Filter

-


-

A guide to using the RAM filter tool.

-


-


-

TAS Editor

-


-

A new tool for making TAS movies.

-


-


-

Convert fcm

-


-

A tool that will convert .fcm movie files to the .fm2 file format.

-


-


-

Auto Fire settings

-


-

A guide for setting auto-fire, auto-fire offset, and alternate A and B options.

-


-


-

Text Hooker

-


-

A guide for using the text hooking tool.

-


-


-

-

Created with the Personal Edition of HelpNDoc: Free Kindle producer

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Tools

+ +
+ +

+

Tools

+


+


+

Guides for the specific tools and settings under FCEUX's Tools menu.

+


+


+

Cheat Search

+


+

A guide to using the cheat search tool.

+


+


+

Memory Watch

+


+

A guide to using the Memory Watch tool.

+


+


+

RAM Filter

+


+

A guide to using the RAM filter tool.

+


+


+

TAS Editor

+


+

A new tool for making TAS movies.

+


+


+

Convert fcm

+


+

A tool that will convert .fcm movie files to the .fm2 file format.

+


+


+

Auto Fire settings

+


+

A guide for setting auto-fire, auto-fire offset, and alternate A and B options.

+


+


+

Text Hooker

+


+

A guide for using the text hooking tool.

+


+


+

+

Created with the Personal Edition of HelpNDoc: Free help authoring tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/TraceLogger.html b/web/help/TraceLogger.html index dad1b9fa..ca3eaf27 100644 --- a/web/help/TraceLogger.html +++ b/web/help/TraceLogger.html @@ -1,104 +1,295 @@ - - + + + + + - Trace Logger - - - - - - - - - - + + + + + + + + Trace Logger + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Trace Logger

- -
- Debug ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Trace Logger

+ +
+

-

Trace Logger

-


-

Introduction

-


-

The Trace Logger logs every executed instruction and every byte of ROM accessed to the window, or a file if you prefer.  Logging to a file is useful if you just want to dump everything that was executed and then search through it later. Logging to the window is useful when you wish to see the instructions that were executed prior to a breakpoint being hit. Both options produce the same data, but the desire to keep that data for a short amount of time or a long amount of time will determine which is best for you.

-


-


-

Using the Trace Logger

-


-

The Trace Logger is a very nice feature which logs each instruction as it is being executed. If you choose to log to the window, you can set how many lines it will retain before discarding old lines. The higher this setting, the more RAM it will consume, but the more lines you'll have available to work with.

-


-

Normally, when logging to window, the Tracer only shows the log if you pause emulator by Pause or Frame Advance hotkey, or by snapping the Debugger. But there is the option to automatically update the log window while the game runs - this is normally useless, unless it is working with the Code/Data Logger to only show newly-executed instructions.

-


-

When the code is logged to window, you can browse it using mouse wheel or vertical scrollbar. Double-clicking any address in this window will bring the Debugger window at this address. Right-clicking any address allows you to label the address (see Symbolic Debug).

-


-

You can customize the format of text output in the log:

-
    -
  • whether to log registers state for every instruction, and where to put the data in every text line (to the left or to the right from the code disassembly)
  • -
  • whether to log current frame number, cycles counter, instructions counter
  • -
  • whether to log emulator messages (such as "State 1 loaded")
  • -
  • whether to log Breakpoint Hits (when you use debugger while tracing)
  • -
  • whether to apply Symbolic Debug names when logging. See Debugger section for details
  • +

    Trace Logger

    +


    +

    Introduction

    +


    +

    The Trace Logger logs every executed instruction and every byte of ROM accessed to the window, or a file if you prefer.  Logging to a file is useful if you just want to dump everything that was executed and then search through it later. Logging to the window is useful when you wish to see the instructions that were executed prior to a breakpoint being hit. Both options produce the same data, but the desire to keep that data for a short amount of time or a long amount of time will determine which is best for you.

    +


    +


    +

    Using the Trace Logger

    +


    +

    The Trace Logger is a very nice feature which logs each instruction as it is being executed. If you choose to log to the window, you can set how many lines it will retain before discarding old lines. The higher this setting, the more RAM it will consume, but the more lines you'll have available to work with.

    +


    +

    Normally, when logging to window, the Tracer only shows the log if you pause emulator by Pause or Frame Advance hotkey, or by snapping the Debugger. But there is the option to automatically update the log window while the game runs - this is normally useless, unless it is working with the Code/Data Logger to only show newly-executed instructions.

    +


    +

    When the code is logged to window, you can browse it using mouse wheel or vertical scrollbar. Double-clicking any address in this window will bring the Debugger window at this address. Right-clicking any address allows you to label the address (see Symbolic Debug).

    +


    +

    You can customize the format of text output in the log:

    +
      +
    • whether to log registers state for every instruction, and where to put the data in every text line (to the left or to the right from the code disassembly)
    • +
    • whether to log current frame number, cycles counter, instructions counter
    • +
    • whether to log emulator messages (such as "State 1 loaded")
    • +
    • whether to log Breakpoint Hits (when you use debugger while tracing)
    • +
    • whether to apply Symbolic Debug names when logging. See Debugger section for details
    -


    -

    For nice visualization of JSRs nesting you can use Stack Pointer for lines tabbing. Since NES games mostly use stack for subroutine calls (and rarely store variables in the stack), this option will likely produce a more readable disassembly. With this option you may also want to put registers data to the left from disassembly text, so they won't be tabbed.

    -


    -

    The Trace Logger has extra options which work with the Code/Data Logger so that Tracer only shows instructions executed for the first time, or those which access data for the first time. This can be quite useful for finding certain key routines or finding otherwise impossible-to-find data in almost any game.  The best way to use this feature is in conjunction with the option to automatically update the window while logging. Then, as you play the game, you can watch new results appear at once. If you're searching for something specific, first try to get everything (EXCEPT what you're looking for) to execute, then watch closely as what you're looking for executes for the first time.

    -


    -

    There are two ways to filter what the Code/Data Logger shows. The first filter lets you log only newly-executed code (so that an instruction is not logged again if it has already been logged). The second logs only instructions when they access data which hadn't been accessed before. Note that both filters can be used at once (which shows bytes that pass either filter).

    -


    -


    -


    -


    +


    +

    For nice visualization of JSRs nesting you can use Stack Pointer for lines tabbing. Since NES games mostly use stack for subroutine calls (and rarely store variables in the stack), this option will likely produce a more readable disassembly. With this option you may also want to put registers data to the left from disassembly text, so they won't be tabbed.

    +


    +

    The Trace Logger has extra options which work with the Code/Data Logger so that Tracer only shows instructions executed for the first time, or those which access data for the first time. This can be quite useful for finding certain key routines or finding otherwise impossible-to-find data in almost any game.  The best way to use this feature is in conjunction with the option to automatically update the window while logging. Then, as you play the game, you can watch new results appear at once. If you're searching for something specific, first try to get everything (EXCEPT what you're looking for) to execute, then watch closely as what you're looking for executes for the first time.

    +


    +

    There are two ways to filter what the Code/Data Logger shows. The first filter lets you log only newly-executed code (so that an instruction is not logged again if it has already been logged). The second logs only instructions when they access data which hadn't been accessed before. Note that both filters can be used at once (which shows bytes that pass either filter).

    +


    +


    +


    +


    -

    Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle

    -
- - + + +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + - -
- - diff --git a/web/help/Troubleshooting.html b/web/help/Troubleshooting.html index a1fd89f3..7b64fecb 100644 --- a/web/help/Troubleshooting.html +++ b/web/help/Troubleshooting.html @@ -1,128 +1,319 @@ - - + + + + + - Troubleshooting - - - - - - - - - - + + + + + + + + Troubleshooting + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Troubleshooting

- -
- FAQ / Guides ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Troubleshooting

-


-


-

This section describes potential problems/question that could arise when using FCEUX.

-


-

Slow emulation / Sound crackle

-


-

FCEUX may not run well on slow CPUs.

-

Ensure that you're using the Old PPU, because the New PPU engine is very slow. Check Config -> PPU -> Old PPU.

-


-


-

Sound crackle

-


-

If you enable hardware acceleration and Vsync (Wait for VBlank), and your monitor has a framerate different from 60FPS, you may experience minor sound cracle. This is a known issue and will probably be resolved in a future release.

-


-


-

Emulated picture is blurred (similar to the bilinear filter)

-


-

Try choosing different options in the "DirectDraw" list in the Video config dialog.

-


-


-

Slow savestates when recording movies

-


-

On slower computers, savestates can be slow with long movies.  A small speedup can be done by disabling Config -> Enable -> Backup savestates.

-


-


-

The colors in game X do not look right!

-


-

There's no such thing as a universally right palette for NES games.

-

FCEUX uses the color palette of the old FCEU / FCEUXD branches. Also FCEUX comes pre-packaged with several additional color palettes. For more information see Palette config and Palette options.

-


-


-

I converted a .fcm file to .fm2, but the .fm2 desyncs

-


-

Depending on what version of FCEU / Game your .fcm was made, there maybe a number of sync issues. In addition, the .fm2 conversion tool has had some issues on certain operating systems including Vista and Mac. you can try using an external program for movie conversion.

-


-


-

Can't find FDS Bios image when I attempt to load a .fds game!

-


-

FCEUX requires the FDS Bios to be named disksys.rom. It must be located in the root directory (where fceux.exe is stored) or in the folder of the FDS Directory override (see Directory overrides).

-


-

In addition, there are some bad versions of disksys.rom. The one FDS requires is 8192 bytes in size.

-


-


-

How can I use Netplay / Where can I get FCEU Server?

-


-

Currently, the Windows version of FCEUX is barely compatible with the FCEU-server code. This is a known issue and will probably be resolved in a future release.

-


-


-

I have a Game Genie rom, how can I use it with FCEUX?

-


-

While FCEUX has a Game Genie code converter, you can also use game genie codes with an old-school Game Genie ROM.  It must be named gg.rom and must be placed in the root directory (where fceux.exe is stored). You must also check Config->Enable->Game Genie ROM in the main menu. Then the Game Genie ROM will activate every time you open a ROM, so you can enter GG codes letter-by-letter like they did in the past.

-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Produce electronic books easily

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Troubleshooting

+ +
+ +

+

Troubleshooting

+


+


+

This section describes potential problems/question that could arise when using FCEUX.

+


+

Slow emulation / Sound crackle

+


+

FCEUX may not run well on slow CPUs.

+

Ensure that you're using the Old PPU, because the New PPU engine is very slow. Check Config -> PPU -> Old PPU.

+


+


+

Sound crackle

+


+

If you enable hardware acceleration and Vsync (Wait for VBlank), and your monitor has a framerate different from 60FPS, you may experience minor sound cracle. This is a known issue and will probably be resolved in a future release.

+


+


+

Emulated picture is blurred (similar to the bilinear filter)

+


+

Try choosing different options in the "DirectDraw" list in the Video config dialog.

+


+


+

Slow savestates when recording movies

+


+

On slower computers, savestates can be slow with long movies.  A small speedup can be done by disabling Config -> Enable -> Backup savestates.

+


+


+

The colors in game X do not look right!

+


+

There's no such thing as a universally right palette for NES games.

+

FCEUX uses the color palette of the old FCEU / FCEUXD branches. Also FCEUX comes pre-packaged with several additional color palettes. For more information see Palette config and Palette options.

+


+


+

I converted a .fcm file to .fm2, but the .fm2 desyncs

+


+

Depending on what version of FCEU / Game your .fcm was made, there maybe a number of sync issues. In addition, the .fm2 conversion tool has had some issues on certain operating systems including Vista and Mac. you can try using an external program for movie conversion.

+


+


+

Can't find FDS Bios image when I attempt to load a .fds game!

+


+

FCEUX requires the FDS Bios to be named disksys.rom. It must be located in the root directory (where fceux.exe is stored) or in the folder of the FDS Directory override (see Directory overrides).

+


+

In addition, there are some bad versions of disksys.rom. The one FDS requires is 8192 bytes in size.

+


+


+

How can I use Netplay / Where can I get FCEU Server?

+


+

Currently, the Windows version of FCEUX is barely compatible with the FCEU-server code. This is a known issue and will probably be resolved in a future release.

+


+


+

I have a Game Genie rom, how can I use it with FCEUX?

+


+

While FCEUX has a Game Genie code converter, you can also use game genie codes with an old-school Game Genie ROM.  It must be named gg.rom and must be placed in the root directory (where fceux.exe is stored). You must also check Config->Enable->Game Genie ROM in the main menu. Then the Game Genie ROM will activate every time you open a ROM, so you can enter GG codes letter-by-letter like they did in the past.

+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create Web Help sites

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/Video.html b/web/help/Video.html index 79eaa41e..864ede69 100644 --- a/web/help/Video.html +++ b/web/help/Video.html @@ -1,168 +1,359 @@ - - + + + + + - Video - - - - - - - - - - + + + + + + + + Video + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Video

- -
- Config ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

Video Configuration

-


-

This window sets various graphics emulation options.

-


-


-

Full Screen Settings

-


-

Full Screen

-

Check this checkbox to enter full screen mode.

-

Alternatively, you can use a hotkey (Alt+Enter by default) or a double-click (if the "Switch fullscreen by double-click" option is enabled in GUI options).

-


-

Enter full screen mode after game is loaded

-

If checked, FCEUX will enter full screen mode when a game is loaded.

-


-

Hide mouse cursor

-

If checked, FCEUX will hide mouse cursor when in full screen mode.

-


-

Mode

-

Sets the image size during full screen mode. By default this is automatically set to match current display resolution. You can change the resolution by entering different values.

-


-

Special Scaler

-

Within this box is eight options: hq2x, Scale2x, NTSC 2x, hq3x, Scale3x, Prescale2x, Prescale3x, and Prescale4x.

-

- Scale2x/3x just attempts to render out the corners of the pixels to make them look a bit rounder. "2x" means two times bigger than 1x1 and "3x" means three times bigger than 1x1.

-

- Hq2x/3x does a much better job than scale2x/3x by smearing the pixels together with a slight blur. However, Hq2x/3x requires a faster computer for decent speed (at least 1 GHz and above). "2x" means two times bigger than 1x1 and "3x" means three times bigger than 1x1.

-

- NTSC 2x simulates visual artifacts that are produced by analog (composite) video sygnal that the real console generates.

-

- Prescale2x/3x/4x upscales the source picture using a pixel based (nearest neighbor) algorithm, that allows to change the level of interpolation, applied when using hardware acceleration.

-


-

Sync Method

-

If the emulator is running poorly, trying out these sync options can help make it run smoother (fix image tearing).

-


-

DirectDraw

-

If the image is blurry, here you can disable hardware acceleration.

-


-


-

Windowed Settings

-


-

Size Multiplier

-

Takes the image size and multiples the X and Y by a specific amount. You can also change these by clicking and dragging the border of the FCEUX window.

-


-

Force Integral Scaling Factors

-

If checked, FCEUX window can only be stretched by even amounts (1x, 2x, 3x, etc.).  If unchecked, it can be stretched by any amount.

-

When you are resizing FCEUX window by dragging its borders, you can hold Shift to temporarily invert this option.

-


-

Force Aspect Ratio Correction

-

Checking this will only allow the correct aspect ratio while resizing the window.

-


-

Special Scaler

-

Within this box is eight options: hq2x, Scale2x, NTSC 2x, hq3x, Scale3x, Prescale2x, Prescale3x, and Prescale4x.

-


-

Sync Method

-

If the emulator is running poorly, trying out these sync options can help make it run smoother (fix image tearing).

-


-

DirectDraw

-

If Vsync doesn't work, here you can enable hardware acceleration.

-

       

-


-
-


-

The following options affect both Fullscreen and windowed mode.

-


-


-

Aspect ratio

-


-

Best Fit

-

This is checked by default, so FCEUX will automatically maintain correct aspect ratio for any size of the window. If you uncheck this, the image will be stretched to fill the whole window area.

-


-

BG color

-

When window size is wider or taller than image size, empty areas of the window are colored black by default. Checking this option will color these areas according to current "background" color of NES palette.

-


-

Square pixels

-

This is checked by default, so FCEUX will limit the max size of the image to make all pixels share the same width/height. If you uncheck this, the image will be stretched to fill the whole width or height of the window area.

-


-

TV Aspect

-

Check this if you want to change the image aspect ratio (e.g. to 4:3). You can enter different values in adjacent text fields.

-


-


-

Drawing Area

-


-

First Line

-

Sets the first scan line for NTSC and PAL Modes. This should be left on the default of 8 for NTSC and 0 for PAL.

-


-

Last Line

-

Sets the last scan line for NTSC and PAL Modes. This should be left on the default of 231 for NTSC and 239 for PAL.

-


-

Clip left and right sides (8 px on each)

-

If enabled, 8 pixels from each side of the windows will be removed. Some NES games show grapical artifacts on the sides of screen when scrolling (on real hardware too!), so you may hide those artifacts by checking the option.

-


-


-

Emulation

-


-

Allow more than 8 sprites per scanline

-

On real NES hardware, more than 8 sprites on the screen causes flickering. Enabling this option can reduce flickering by allowing more sprites to be visible at once. But if you prefer to stay "true" to NES hardware, this should not be checked, because some games rely on the limitation.

-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Create iPhone web-based documentation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Video

+ +
+ +

+

Video Configuration

+


+

This window sets various graphics emulation options.

+


+


+

Full Screen Settings

+


+

Full Screen

+

Check this checkbox to enter full screen mode.

+

Alternatively, you can use a hotkey (Alt+Enter by default) or a double-click (if the "Switch fullscreen by double-click" option is enabled in GUI options).

+


+

Enter full screen mode after game is loaded

+

If checked, FCEUX will enter full screen mode when a game is loaded.

+


+

Hide mouse cursor

+

If checked, FCEUX will hide mouse cursor when in full screen mode.

+


+

Mode

+

Sets the image size during full screen mode. By default this is automatically set to match current display resolution. You can change the resolution by entering different values.

+


+

Special Scaler

+

Within this box is eight options: hq2x, Scale2x, NTSC 2x, hq3x, Scale3x, Prescale2x, Prescale3x, and Prescale4x.

+

- Scale2x/3x just attempts to render out the corners of the pixels to make them look a bit rounder. "2x" means two times bigger than 1x1 and "3x" means three times bigger than 1x1.

+

- Hq2x/3x does a much better job than scale2x/3x by smearing the pixels together with a slight blur. However, Hq2x/3x requires a faster computer for decent speed (at least 1 GHz and above). "2x" means two times bigger than 1x1 and "3x" means three times bigger than 1x1.

+

- NTSC 2x simulates visual artifacts that are produced by analog (composite) video sygnal that the real console generates.

+

- Prescale2x/3x/4x upscales the source picture using a pixel based (nearest neighbor) algorithm, that allows to change the level of interpolation, applied when using hardware acceleration.

+


+

Sync Method

+

If the emulator is running poorly, trying out these sync options can help make it run smoother (fix image tearing).

+


+

DirectDraw

+

If the image is blurry, here you can disable hardware acceleration.

+


+


+

Windowed Settings

+


+

Size Multiplier

+

Takes the image size and multiples the X and Y by a specific amount. You can also change these by clicking and dragging the border of the FCEUX window.

+


+

Force Integral Scaling Factors

+

If checked, FCEUX window can only be stretched by even amounts (1x, 2x, 3x, etc.).  If unchecked, it can be stretched by any amount.

+

When you are resizing FCEUX window by dragging its borders, you can hold Shift to temporarily invert this option.

+


+

Force Aspect Ratio Correction

+

Checking this will only allow the correct aspect ratio while resizing the window.

+


+

Special Scaler

+

Within this box is eight options: hq2x, Scale2x, NTSC 2x, hq3x, Scale3x, Prescale2x, Prescale3x, and Prescale4x.

+


+

Sync Method

+

If the emulator is running poorly, trying out these sync options can help make it run smoother (fix image tearing).

+


+

DirectDraw

+

If Vsync doesn't work, here you can enable hardware acceleration.

+

         

+


+
+


+

The following options affect both Fullscreen and windowed mode.

+


+


+

Aspect ratio

+


+

Best Fit

+

This is checked by default, so FCEUX will automatically maintain correct aspect ratio for any size of the window. If you uncheck this, the image will be stretched to fill the whole window area.

+


+

BG color

+

When window size is wider or taller than image size, empty areas of the window are colored black by default. Checking this option will color these areas according to current "background" color of NES palette.

+


+

Square pixels

+

This is checked by default, so FCEUX will limit the max size of the image to make all pixels share the same width/height. If you uncheck this, the image will be stretched to fill the whole width or height of the window area.

+


+

TV Aspect

+

Check this if you want to change the image aspect ratio (e.g. to 4:3). You can enter different values in adjacent text fields.

+


+


+

Drawing Area

+


+

First Line

+

Sets the first scan line for NTSC and PAL Modes. This should be left on the default of 8 for NTSC and 0 for PAL.

+


+

Last Line

+

Sets the last scan line for NTSC and PAL Modes. This should be left on the default of 231 for NTSC and 239 for PAL.

+


+

Clip left and right sides (8 px on each)

+

If enabled, 8 pixels from each side of the windows will be removed. Some NES games show grapical artifacts on the sides of screen when scrolling (on real hardware too!), so you may hide those artifacts by checking the option.

+


+


+

Emulation

+


+

Allow more than 8 sprites per scanline

+

On real NES hardware, more than 8 sprites on the screen causes flickering. Enabling this option can reduce flickering by allowing more sprites to be visible at once. But if you prefer to stay "true" to NES hardware, this should not be checked, because some games rely on the limitation.

+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew200.html b/web/help/WhatsNew200.html index dbb322bf..5e944292 100644 --- a/web/help/WhatsNew200.html +++ b/web/help/WhatsNew200.html @@ -1,178 +1,369 @@ - - + + + + + - What's New? 2.0.0 - - - - - - - - - - + + + + + + + + What's New? 2.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.0.0

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.0.0

-

Released August 02, 2008

-


-

FCEUX has all the latest tools, enhancements, and features from FCEU 0.28 rerecording and FCEUXDSP 1.07  In addition, it has many new tools, bug fixes, and enhancements not seen in previous branches.

-


-


-

General

-


-

-A detailed Help Menu!  No longer are you aimlessly searching the internet for long lost info on FCEU's options!

-

-Numerous Dialog box reformats.

-

-FCEU remembers its last screen (x,y) position.

-

-Increased command line options

-

-More options under the Directory Override Menu

-

-A Turbo Toggle option (turbo now can be toggled on rather than having to hold the key down)

-

-More hotkey assignable options in the Map Hotkeys Menu.

-

-A lag counter

-

-Autofire uses the lag counter (so it will skip over lag frames)

-


-


-

Movie support

-


-

Overhauls in both the movie and savestate file formats.

-


-

.fm2 File format

-


-

The .fcm file format has been overhauled into a new .fm2 format.  Changes include:

-


-

-Uncompressed and text based format.  Movie editing can be done simply in a text editor.

-

-Recording from soft reset option removed.

-

-Recording from start (hard reset) no longer has an empty savestate at the beginning.

-

-GUID inserted into movies for better savestate/loadstate error handling.

-

-Rather than an Author field, it has a full metadata menu where an author can put any info needed.

-

-A tool to convert .fcm files to .fm2 files.

-

-More specific info on .fm2 files in the .fm2 documentation.

-


-

Savestate/Loadstate

-


-

-New savestate file format.  NOTE:  Savestates from previous FCEU versions CAN NOT be used in FCEUX.

-

-Fully functional error handling (savestates from other movies cannot be loaded).

-

-Read-only toggling related bugs fixed.

-

-Savestate filenames include the name of the movie (if a movie was playing when made).  This prevents loading wrong savestates. (This also means that savestate 0 is different when a movie is playing and when it is not).

-


-

7z Archive Support

-


-

-ROMs in any 7z compatible compressed format can be opened directly.

-

-If more than one valid ROM exists in an archive file, then a dialog box will open with a list of available ROM choices.

-


-

TAS Edit

-


-

-A brand new powerful movie making tool that revolutionizes the way TAS movies are made.  See TAS edit.

-


-


-

New Tools

-


-

TAS Edit - a revolutionary new way of making TAS movies.

-


-

Input Presets - a system for quickly toggling different input configurations.

-


-


-

Tool Upgrades

-


-

Numerous enhancements have been made to various Tools/Options.

-


-

Memory Watch

-


-

-Resource management optimized so that memory watch now uses a minimal amount of CPU

-

-FCEUX remembers memory watch's last screen position (x,y)

-

-Tab-able Edit boxes

-

-Edit boxes now can hold 64 characters

-

-A Menu bar for all Memory watch functions

-

-Both "Save as" and "Save" options

-

-Hotkeys for New, Open, Save, Save As and Close

-

-A recent files Menu

-

-A "load on startup" option. If checked, memory watch will open automatically when FCEUX is opened

-

-A "load last file" option.  If checked, memory watch will load the last file used

-


-

Cheat Search

-


-

-Now has a minimize button

-

-Cheat Search Menu from FCEUXDSP (a major overhaul compared to other FCEU branches)

-

-Possibilities update while playing/frame advancing a game

-

-Double clicking a value in the possibilities window sends the value directly to Memory Watch

-


-

RAM Filter

-


-

-Double clicking a value in the possibilities window sends the value directly to Memory Watch

-


-


-

Lua Scripting

-


-

-Uses the latest features of Lua Scripting from FCEU 0.28

-

-Many enhancements and new commands including dialog creation commands!  Now scripts can create their own dialog's and GUI features.

-


-

Lua Basic Bot

-


-

-Basicbot removed (from the rerecording version of FCE Ultra).  In its place is lua bot.

-


-


-

AVI Recording

-


-

-"Movie playback stopped" message recorded in AVI by default

-

-Turbo Toggle Hotkey.  (Allows turbo to be left on for a faster AVI capture).

-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured Help generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.0.0

+ +
+ +

+

What's New? 2.0.0

+

Released August 02, 2008

+


+

FCEUX has all the latest tools, enhancements, and features from FCEU 0.28 rerecording and FCEUXDSP 1.07  In addition, it has many new tools, bug fixes, and enhancements not seen in previous branches.

+


+


+

General

+


+

-A detailed Help Menu!  No longer are you aimlessly searching the internet for long lost info on FCEU's options!

+

-Numerous Dialog box reformats.

+

-FCEU remembers its last screen (x,y) position.

+

-Increased command line options

+

-More options under the Directory Override Menu

+

-A Turbo Toggle option (turbo now can be toggled on rather than having to hold the key down)

+

-More hotkey assignable options in the Map Hotkeys Menu.

+

-A lag counter

+

-Autofire uses the lag counter (so it will skip over lag frames)

+


+


+

Movie support

+


+

Overhauls in both the movie and savestate file formats.

+


+

.fm2 File format

+


+

The .fcm file format has been overhauled into a new .fm2 format.  Changes include:

+


+

-Uncompressed and text based format.  Movie editing can be done simply in a text editor.

+

-Recording from soft reset option removed.

+

-Recording from start (hard reset) no longer has an empty savestate at the beginning.

+

-GUID inserted into movies for better savestate/loadstate error handling.

+

-Rather than an Author field, it has a full metadata menu where an author can put any info needed.

+

-A tool to convert .fcm files to .fm2 files.

+

-More specific info on .fm2 files in the .fm2 documentation

+


+

Savestate/Loadstate

+


+

-New savestate file format.  NOTE:  Savestates from previous FCEU versions CAN NOT be used in FCEUX.

+

-Fully functional error handling (savestates from other movies cannot be loaded).

+

-Read-only toggling related bugs fixed.

+

-Savestate filenames include the name of the movie (if a movie was playing when made).  This prevents loading wrong savestates. (This also means that savestate 0 is different when a movie is playing and when it is not).

+


+

7z Archive Support

+


+

-ROMs in any 7z compatible compressed format can be opened directly.

+

-If more than one valid ROM exists in an archive file, then a dialog box will open with a list of available ROM choices.

+


+

TAS Edit

+


+

-A brand new powerful movie making tool that revolutionizes the way TAS movies are made.  See TAS edit.

+


+


+

New Tools

+


+

TAS Edit - a revolutionary new way of making TAS movies.

+


+

Input Presets - a system for quickly toggling different input configurations.

+


+


+

Tool Upgrades

+


+

Numerous enhancements have been made to various Tools/Options.

+


+

Memory Watch

+


+

-Resource management optimized so that memory watch now uses a minimal amount of CPU

+

-FCEUX remembers memory watch's last screen position (x,y)

+

-Tab-able Edit boxes

+

-Edit boxes now can hold 64 characters

+

-A Menu bar for all Memory watch functions

+

-Both "Save as" and "Save" options

+

-Hotkeys for New, Open, Save, Save As and Close

+

-A recent files Menu

+

-A "load on startup" option. If checked, memory watch will open automatically when FCEUX is opened

+

-A "load last file" option.  If checked, memory watch will load the last file used

+


+

Cheat Search

+


+

-Now has a minimize button

+

-Cheat Search Menu from FCEUXDSP (a major overhaul compared to other FCEU branches)

+

-Possibilities update while playing/frame advancing a game

+

-Double clicking a value in the possibilities window sends the value directly to Memory Watch

+


+

RAM Filter

+


+

-Double clicking a value in the possibilities window sends the value directly to Memory Watch

+


+


+

Lua Scripting

+


+

-Uses the latest features of Lua Scripting from FCEU 0.28

+

-Many enhancements and new commands including dialog creation commands!  Now scripts can create their own dialog's and GUI features.

+


+

Lua Basic Bot

+


+

-Basicbot removed (from the rerecording version of FCE Ultra).  In its place is lua bot.

+


+


+

AVI Recording

+


+

-"Movie playback stopped" message recorded in AVI by default

+

-Turbo Toggle Hotkey.  (Allows turbo to be left on for a faster AVI capture).

+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create Help documents

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew201.html b/web/help/WhatsNew201.html index 76c46871..13b1c696 100644 --- a/web/help/WhatsNew201.html +++ b/web/help/WhatsNew201.html @@ -1,86 +1,277 @@ - - + + + + + - What's New? 2.0.1 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.0.1 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.0.1 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.0.1

-

Released August 04, 2008

-


-

This was a maintenance release that fixes a few oversights in the 2.0.0 release.

-


-

* reorganize display toggle options in the menu

-

* autofire fix (wasn't initializing to any autofire pattern from a fresh .cfg)

-

* homebrew mmc5 games now have 64KB of exwram instead of only 8KB

-

* fix crash related to player2 in lua scripts

-

* fixed player2 in lua scripts

-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured Kindle eBooks generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.0.1 (changelog)

+ +
+ +

+

What's New? 2.0.1

+

Released August 04, 2008

+


+

This was a maintenance release that fixes a few oversights in the 2.0.0 release.

+


+

* reorganize display toggle options in the menu

+

* autofire fix (wasn't initializing to any autofire pattern from a fresh .cfg)

+

* homebrew mmc5 games now have 64KB of exwram instead of only 8KB

+

* fix crash related to player2 in lua scripts

+

* fixed player2 in lua scripts

+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free Kindle producer

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew202.html b/web/help/WhatsNew202.html index db73a65d..9912c93a 100644 --- a/web/help/WhatsNew202.html +++ b/web/help/WhatsNew202.html @@ -1,166 +1,357 @@ - - + + + + + - What's New? 2.0.2 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.0.2 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.0.2 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.0.2

-

Released August 14, 2008

-


-

This release includes a large number of bug fixes, feature enhancements, and new features.

-


-


-

Fixed Crashing Bugs

-


-

* restore savestate error recovery functionality.  Will prevent crashes after savestate error messages

-

* Fixed - Low speeds (1%) crash FCEUX

-

* fixes bug where palflag 1 in .fm2 files crashes fceux

-

* FCEUX no longer crashes when attempting to open a non movie file

-

* Buffer overflow (change vsprintf to vsnprintf)

-


-

Minor Bug fixes

-


-

* SRAM not wiped on power cycle (during movies)

-

* Moviefilenames without extension now automatically get fm2

-

* auto-fill .fcs extension in save state as dialog

-

* FCM>FM2 converter releases file handle

-

* fix a new bug in windows build which caused fourscore emulation to fail in some cases

-

* Player 3 no longer inputs when not used

-

* prints a special message when trying to open an FCM reminding user to convert.

-

* fixes bug where Avi recording with no sound messes up the format

-

* Fixed bug where Convert .fcm didn't do special characters

-

* fixed the (null) in the default lua directory listing

-

* Ctrl+X now works in the memory watch dialog

-

* Dialog window positions won't "disappear" (-32000 protection on all dialogs that remember x,y)

-

* fixed View Slots bug - will now always show the used slots

-


-

* added shift+L as default hotkey for reload lua script

-

* added input display to the FCEUX main menu

-

* change config filename from fceu98.cfg to fceux.cfg

-


-

New Features

-


-

* restore IPS patching capability which was lost when archive support was added

-

* restore ungzipping (and unzipping in sdl) capability which was lost when archive support was added

-

* re-enable an "author" text field in the record movie dialog

-

* re-enable support for old-format savestates. (Note: can not be loaded into a movie!)

-


-

* Added new toggle - frame adv. - lag skip (menu item + hotkey mapping + saved in config), will cause frame adv. to skip frames where input is not read

-

* Added support for loading movies from archives (just like ROM files).  Note: Movies loaded from an archive file will be read-only.

-

* movie replay dialog displays fractions of a second on movie length

-


-

* Savestates now save the Lagcounter information.

-

* added a mute turbo option in sound config

-


-

* add an option to pick a constant color to draw in place of BG when BG rendering is disabled (look for gNoBGFillColor in config).

-


-

Mappers

-


-

* remove cnrom chr rom size limit for homebrew roms

-

* mmc5 - 64KB WRAM games now work correctly

-

* mmc5 - use of chr A regs for BG in sprite 8x8 mode is fixed

-

* upgrade to cah4e3's latest mapper 163&164 code to fix a crash in a game

-


-


-

Debugging Tools

-


-

* Debugger - restore snap functionality

-

* Debugger - add FORBID breakpoints - regions which block breakpoints from happening if they contain the PC

-

* Debugger - debugger window is now resizeable

-

* nametable viewer  will display correct NT,CHR,ATTR data in more cases (specifically, including some exotic mmc5 cases).

-


-

Lua

-


-

* Savestates remember Lua painting

-

* add memory.readbyterange to emulua

-


-

SDL only

-


-

* SDL: fixed --input(1-4) options.  input1 and 2 are regular inputs, input3 and 4 are famicom expansion inputs

-

* SDL fix configfile woes. configfile now goes to ~/.fceux/fceux.cfg

-

* SDL: fixed segfault when opening .fcm files

-

* SDL: Saner sound defaults for less choppy sound

-

* SDL: "--special" option fixed for special video scaling filters

-

* SDL: cleaned up the SConsruct

-

* SDL: fixed issue where fceu would lock up when file dialogs were opened during fullscreen

-

* SDL: fixed bug where fceux would close when file dialogs were closed

-

* SDL: File open dialog is now used to movie playback

-

* SDL: File open wrapper now takes a titlebar argument

-

* SDL: Cleanup of usage

-

* SDL: rename options --no8lim -> --nospritelim and --color -> --ntsccolor

-

* SDL: Screenshots now always prepend the game name.

-

* SDL: Changed default A/B from numpad 2 and 3 to j and k.

-

* SDL: Enable frameskip by default

-

* SDL: Fixed a bug that would crash fceux if the emulation speed was overincreased

-

* SDL: New default hotkeys to more closely match win32 defaults

-

* SDL: Added lua script loading hotkey (f3).  Non win32 SDL requires zenity for this to function.

-

* SDL: Build script cleanup; also added option for DEBUG builds.

-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.0.2 (changelog)

+ +
+ +

+

What's New? 2.0.2

+

Released August 14, 2008

+


+

This release includes a large number of bug fixes, feature enhancements, and new features.

+


+


+

Fixed Crashing Bugs

+


+

* restore savestate error recovery functionality.  Will prevent crashes after savestate error messages

+

* Fixed - Low speeds (1%) crash FCEUX

+

* fixes bug where palflag 1 in .fm2 files crashes fceux

+

* FCEUX no longer crashes when attempting to open a non movie file

+

* Buffer overflow (change vsprintf to vsnprintf)

+


+

Minor Bug fixes

+


+

* SRAM not wiped on power cycle (during movies)

+

* Moviefilenames without extension now automatically get fm2

+

* auto-fill .fcs extension in save state as dialog

+

* FCM>FM2 converter releases file handle

+

* fix a new bug in windows build which caused fourscore emulation to fail in some cases

+

* Player 3 no longer inputs when not used

+

* prints a special message when trying to open an FCM reminding user to convert.

+

* fixes bug where Avi recording with no sound messes up the format

+

* Fixed bug where Convert .fcm didn't do special characters

+

* fixed the (null) in the default lua directory listing

+

* Ctrl+X now works in the memory watch dialog

+

* Dialog window positions won't "disappear" (-32000 protection on all dialogs that remember x,y)

+

* fixed View Slots bug - will now always show the used slots

+


+

* added shift+L as default hotkey for reload lua script

+

* added input display to the FCEUX main menu

+

* change config filename from fceu98.cfg to fceux.cfg

+


+

New Features

+


+

* restore IPS patching capability which was lost when archive support was added

+

* restore ungzipping (and unzipping in sdl) capability which was lost when archive support was added

+

* re-enable an "author" text field in the record movie dialog

+

* re-enable support for old-format savestates. (Note: can not be loaded into a movie!)

+


+

* Added new toggle - frame adv. - lag skip (menu item + hotkey mapping + saved in config), will cause frame adv. to skip frames where input is not read

+

* Added support for loading movies from archives (just like ROM files).  Note: Movies loaded from an archive file will be read-only.

+

* movie replay dialog displays fractions of a second on movie length

+


+

* Savestates now save the Lagcounter information.

+

* added a mute turbo option in sound config

+


+

* add an option to pick a constant color to draw in place of BG when BG rendering is disabled (look for gNoBGFillColor in config).

+


+

Mappers

+


+

* remove cnrom chr rom size limit for homebrew roms

+

* mmc5 - 64KB WRAM games now work correctly

+

* mmc5 - use of chr A regs for BG in sprite 8x8 mode is fixed

+

* upgrade to cah4e3's latest mapper 163&164 code to fix a crash in a game

+


+


+

Debugging Tools

+


+

* Debugger - restore snap functionality

+

* Debugger - add FORBID breakpoints - regions which block breakpoints from happening if they contain the PC

+

* Debugger - debugger window is now resizeable

+

* nametable viewer  will display correct NT,CHR,ATTR data in more cases (specifically, including some exotic mmc5 cases).

+


+

Lua

+


+

* Savestates remember Lua painting

+

* add memory.readbyterange to emulua

+


+

SDL only

+


+

* SDL: fixed --input(1-4) options.  input1 and 2 are regular inputs, input3 and 4 are famicom expansion inputs

+

* SDL fix configfile woes. configfile now goes to ~/.fceux/fceux.cfg

+

* SDL: fixed segfault when opening .fcm files

+

* SDL: Saner sound defaults for less choppy sound

+

* SDL: "--special" option fixed for special video scaling filters

+

* SDL: cleaned up the SConsruct

+

* SDL: fixed issue where fceu would lock up when file dialogs were opened during fullscreen

+

* SDL: fixed bug where fceux would close when file dialogs were closed

+

* SDL: File open dialog is now used to movie playback

+

* SDL: File open wrapper now takes a titlebar argument

+

* SDL: Cleanup of usage

+

* SDL: rename options --no8lim -> --nospritelim and --color -> --ntsccolor

+

* SDL: Screenshots now always prepend the game name.

+

* SDL: Changed default A/B from numpad 2 and 3 to j and k.

+

* SDL: Enable frameskip by default

+

* SDL: Fixed a bug that would crash fceux if the emulation speed was overincreased

+

* SDL: New default hotkeys to more closely match win32 defaults

+

* SDL: Added lua script loading hotkey (f3).  Non win32 SDL requires zenity for this to function.

+

* SDL: Build script cleanup; also added option for DEBUG builds.

+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free help authoring environment

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew203.html b/web/help/WhatsNew203.html index 20100676..edecadc5 100644 --- a/web/help/WhatsNew203.html +++ b/web/help/WhatsNew203.html @@ -1,126 +1,317 @@ - - + + + + + - What's New? 2.0.3 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.0.3 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.0.3 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.0.2

-

Released November 02, 2008

-


-

This release includes some key bug fixes and feature enhancements.

-


-


-

Major Bug / Crash Bug Fixes

-


-

* Reset/Power-on recording for .fm2 files!

-

* fix ..fcm conversion, recording, and playback of reset and power commands

-

* Win32 - auto-load the only useful ROM or movie from an archive, in cases where there is only one

-

* Win32 - permit user optionally to proceed through the movie savestate mismatch error condition, in case he knows what he is doing.

-

* Win32 - fix a bug in the savestate recovery code which prevent aborted savestate loads from recovering emulator state correctly.

-

* gracefully handle non-convertible broken UTF-8 text without crashing

-

* Win32 - don't read every archive file when scanning for replay dialog. scan them, and only look for *.fm2

-


-

New Features Win32

-


-

* Win32 - added a toggle for binding savestates to movies

-

* Win32 - added -cfg (config file) command line argument

-


-

Minor Bug fixes

-


-

* Win32 - Sound config dialog will now look to see if Mute Turbo should be checked

-

* Win32 - Debugger - Fix Child windows inside debugging window get invalid sizes

-

* Win32 - bind a menu option for display frame counter

-

* Win32 - fix problem where replay dialog couldn't work when the process current directory had changed to something other than emulator base directory

-

* Lua ignores second joypad.set()

-

* Load state as... does not use the savestate override dir (fixed; now, it does)

-

*Win32 - debugger - fix issue where keyboard keys get stuck when switching between debugger window and main window

-


-


-

SDL

-


-

* SDL - added support for AVI creation for SDL, see documentation/Videolog.txt for more

-

* SDL - --inputcfg can now be used without a filename

-

* SDL - should fix issues with missing author field crashing FCEUX

-

* SDL - toggle lag frame counter for SDL, default hotkey F8

-

* SDL - toggle skipping of lag frames for SDL, default hotkey F6

-

* SDL - user ability to toggle "bind savestates to movie" added for SDL, default hotkey F2

-

* SDL - Lua is now optional, thanks Shinydoofy for a patch.  also fixed some build issues.

-

* SDL - fixed an issue where flawed movie would crash FCEUX on every startup

-

* SDL - fixed issue where windowed mode would always be set to 32 bpp

-

* SDL - fixed ppc build errors and added LSB_FIRST option to build scripts

-

* SDL - --newppu option added to SDL, disabled by default

-


-

GFCEUX (SDL)

-


-

* GFCEUX - made the input config window more usable

-

* GFCEUX - added uninstall script for GFCEUX

-


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create PDF Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.0.3 (changelog)

+ +
+ +

+

What's New? 2.0.2

+

Released November 02, 2008

+


+

This release includes some key bug fixes and feature enhancements.

+


+


+

Major Bug / Crash Bug Fixes

+


+

* Reset/Power-on recording for .fm2 files!

+

* fix ..fcm conversion, recording, and playback of reset and power commands

+

* Win32 - auto-load the only useful ROM or movie from an archive, in cases where there is only one

+

* Win32 - permit user optionally to proceed through the movie savestate mismatch error condition, in case he knows what he is doing.

+

* Win32 - fix a bug in the savestate recovery code which prevent aborted savestate loads from recovering emulator state correctly.

+

* gracefully handle non-convertible broken UTF-8 text without crashing

+

* Win32 - don't read every archive file when scanning for replay dialog. scan them, and only look for *.fm2

+


+

New Features Win32

+


+

* Win32 - added a toggle for binding savestates to movies

+

* Win32 - added -cfg (config file) command line argument

+


+

Minor Bug fixes

+


+

* Win32 - Sound config dialog will now look to see if Mute Turbo should be checked

+

* Win32 - Debugger - Fix Child windows inside debugging window get invalid sizes

+

* Win32 - bind a menu option for display frame counter

+

* Win32 - fix problem where replay dialog couldn't work when the process current directory had changed to something other than emulator base directory

+

* Lua ignores second joypad.set()

+

* Load state as... does not use the savestate override dir (fixed; now, it does)

+

*Win32 - debugger - fix issue where keyboard keys get stuck when switching between debugger window and main window

+


+


+

SDL 

+


+

* SDL - added support for AVI creation for SDL, see documentation/Videolog.txt for more

+

* SDL - --inputcfg can now be used without a filename

+

* SDL - should fix issues with missing author field crashing FCEUX

+

* SDL - toggle lag frame counter for SDL, default hotkey F8

+

* SDL - toggle skipping of lag frames for SDL, default hotkey F6

+

* SDL - user ability to toggle "bind savestates to movie" added for SDL, default hotkey F2

+

* SDL - Lua is now optional, thanks Shinydoofy for a patch.  also fixed some build issues.

+

* SDL - fixed an issue where flawed movie would crash FCEUX on every startup

+

* SDL - fixed issue where windowed mode would always be set to 32 bpp

+

* SDL - fixed ppc build errors and added LSB_FIRST option to build scripts

+

* SDL - --newppu option added to SDL, disabled by default

+


+

GFCEUX (SDL)

+


+

* GFCEUX - made the input config window more usable

+

* GFCEUX - added uninstall script for GFCEUX

+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create EBooks

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew210.html b/web/help/WhatsNew210.html index 2e537e11..1660f8a6 100644 --- a/web/help/WhatsNew210.html +++ b/web/help/WhatsNew210.html @@ -1,246 +1,437 @@ - - + + + + + - What's New? 2.1 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.1 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.1 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.1

-

Released March 29, 2009

-


-

This release includes a multitude of new features, major fixes, and enhancements.

-


-


-

New Features Win32

-


-

*The latest mappers and mapper fixes from FCEU-mm.  Adds support for many new games such as Warioland II (Unl), Shu Qi Yu,  and Street Dance

-

*Full screen mode fixed!  Also, Alt+Enter properly toggles full screen.

-

*Individual control for sound channels! (See sound config for details).

-

*Undo/Redo Savestate/Loadstate features installed!  No more loss of data to unintentional presses.  (See getting started for details).

-

*Movie subtitles can now be included in .fm2 files.  See .fm2 documentation for details and Movie options for details on customizing.

-

*Auto-backup for movie files.  (See movie options for details).

-

*A Ram change monitor for the Memory watch dialog. (see memwatch for details).

-

*Frame counter works even without a movie loaded.

-

*AVI Directory Override option.

-


-

Major Bug / Crash Bug Fixes

-


-

*Fixed throttling problems that resulted on AMD Dualcore processors. (Caused FCEUX to appear to be in turbo mode).

-

*Fix major crash issue where NROM game (such as SMB) savestates were writing erroneous information if a non NROM game was loaded prior.

-

*Fixed a bug that caused a new sav file to not get created when loading a 2nd battery backed game.

-

*Fix Directory Overrides so to allow users to have no override.  Also fixes directory override reset bug.

-


-

Minor Bug fixes

-


-

*Hotkeys - prevent "Hotkey explosion" where some laptop keys set off all unassigned hotkeys

-

*Timing - "disable throttling when sound is off" now only affects FCEUX when sound is off

-

*Clip Left and Right sides taken into account when drawing on screen (record/play/pause, lag & frame counters, messages, etc)

-

*Fixed bug where having sound off and Mute turbo caused chirps when toggling

-

*Video settings - fixed bug when both aspect ratio correction and special scaling 3x are set, video was getting resized incorrectly

-

*Auto-save cleanup -prevent loading an auto-save from previous session.  Added flags for enabling auto-save menu item.

-

*Fixed issues related to big endian compiling.

-

*Fix bug so that Escape can now be assigned as a hotkey

-

*Fixed bug in screenshot numbering that caused numbering to not reset when changing games.

-


-

GUI / Menu Enhancements

-


-

*A right-click context menu added!  Includes many commonly used items for a variety of situations.

-

*Menu items that are hotkey mappable now show their current hotkey mapping

-

*Major overhaul to the Menu organization.  

-

*All FCEUX features are now accessible in the menu

-

*Alt Menu Shortcuts properly configured

-

*Menu items are properly grayed when not useable

-

*All movie related menu items moved to a Movie options dialog

-

*Removed hard-coded Accel keys and replaced with re-mappable hotkeys (Open & Close ROM)

-

*Drag & Drop for .fm2 and .lua files

-

*Many new functions added to the context menu (See context menu for details)

-

*New Mappable Hotkeys: Open Cheats, Open ROM, Close ROM, Undo/Redo savestate, Toggle Movie Subtitles

-


-

Lua

-


-

*Added input.get() !  Returns the mouse info and all keyboard buttons pressed by the user.

-

*Fixed joypad.set().  False now sets a button to off.  Nil does not affect the button at all (allowing the user to still control it).

-

*gui.text() Increased height (to approx. 7 lines).

-

*speedmode("turbo") now turns on turbo (which employs frame-skipping) rather than max speed.

-

*memory.readbyte will recognize frozen addresses (cheats).

-

*movie.framecount() always return a number, even when no movie is playing (since the frame counter is implemented without a movie loaded).

-

*Added FCEU.poweron()

-

*Added FCEU.softreset()

-

*Added FCEU.lagged()

-

*Added FCEU.lagcount()

-

*Added FCEU.getreadonly()

-

*Added FCEU.setreadonly()

-

*Added FCEU.fceu_setrenderplanes(sprites, background)

-

*Added movie.active()

-

*Added movie.rerecordcount()

-

*Added movie.length()

-

*Added movie.getname()

-

*Added movie.playbeginning()

-

*Added -lua command line argment, loads a Lua script on startup

-

*Added zapper.read() - returns the zapper (mouse) data.  (Currently does return zapper data in movie playback).

-

*Added joypad.write and joypad.get for naming consistency.

-

*Added rom.readbyte()

-

*Added rom.readbytesigned()

-


-

Sound Config

-


-

*Turning sound off disabled sound config controls

-

*Re-enabled sound buffer time slider control

-


-

Hex Editor

-


-

*Freezing ram addresses automatically updates the Cheats dialog if it is open.

-

* Added prevention from freezing more than 256 addresses at once (doing so caused crash bugs).

-

*Dialog remembers window size.

-

*Dump Rom & Dump PPU to file Dialogs use ROM to build default filename

-

*Maximize and minimize buttons added.

-

*Help menu item added

-


-

Memory Watch

-


-

*Dialog now includes Ram change monitoring. (see memwatch for details).

-

*Dialog is now collapsible to 1 column.

-

*No longer crashes when attempting to load an invalid file from the recent file menu.

-

*Cancel option added to the save changes dialog.

-

*Memory address values that are frozen by the debugger or hex editor are displayed in blue.

-

*Fixed bug that caused dialog to "disappear" due to saving -32000 as its window position.

-

*Save as dialog uses ROM name to build a default memory watch filename if there was no last used memory watch filename

-

*Drag and drop for .txt (memory watch) files.

-

*Minor menu and hotkey fixes.

-

*Watch values now compatible with custom windows dialog colors.

-


-

Debugger

-


-

*Shows scanlines and PPU pixel values

-

*Shows scanlines even while in VBlank

-

*Added a Run Line button (runs 1 scanline per click)

-

*Run 128 Lines button (runs 128 scanlines per click)

-

*Number of active cheats listed.

-

*Cheats list automatically updated if ram addresses are frozen in the hex editor.

-

*Fixed bug that caused dialog to "disappear" due to saving -32000 as its window position.

-

*Debugger now has a minimum valid size

-

*Added "Restore original window size" button

-


-

PPU Viewer

-


-

*Default refresh value set to 15

-

*Refresh value stored in the .cfg file

-


-

Nametable Viewer

-


-

*Default refresh value set to 15

-

*Refresh value stored in the .cfg file

-


-

Trace Logger

-


-

*Fixed bug where user can't scroll the log window while it is auto-updating.

-

*Changed message about F2 pause (left over from FCEUXDSP) to display the current hotkey mapping.

-


-

Text Hooker

-


-

*Saving a .tht file no longer crashes

-

*Dialog updates every frame

-

*Initialization error checking reinstalled,

-

*Dialog remembers window position

-

*Fixed bug where canceling save as produces an error message.

-

*Save As produces default filename based on the current ROM

-


-

Message Log

-


-

*Remembers X,Y position

-

*Resized width and height

-

*Allowed more lines of text to appear on the screen at once.

-


-

Metadata

-


-

*Remembers window position

-

*Can be called from the context menu if a movie is loaded (see context menu for details).

-


-

TASEdit

-


-

*added help menu item

-

*disabled menu items that are not currently implemented.

-


-

Turbo

-

*Turbo now employs frame skip, greatly increasing its speed

-

*The mute turbo option completely bypasses sound processing (another big speed boost)

-

*Turbo now works with the Lazy wait for VBlank sync setting

-


-

SDL

-

*SDL Movie subtitle support and subtitle toggle hotkey added.

-

*SDL Added fcm to fm2 converter tool to SDL version.

-

*SDL Improved the SDL sound code; drastically improves quality of sound.

-

*SDL Savestate slots are now mappable.

-

*SDL Major updates to SDL documentation

-

*SDL Added Shift+M for toggling automatic movie backups.

-

*SDL Added option to mute FCEUX for avi capturing, check the documentation for more details.

-

*SDL Added --noconfig command line option

-

*SDL Frame Advance Skip Lag frames toggle implemented

-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.1 (changelog)

+ +
+ +

+

What's New? 2.1

+

Released March 29, 2009

+


+

This release includes a multitude of new features, major fixes, and enhancements.

+


+


+

New Features Win32

+


+

*The latest mappers and mapper fixes from FCEU-mm.  Adds support for many new games such as Warioland II (Unl), Shu Qi Yu,  and Street Dance

+

*Full screen mode fixed!  Also, Alt+Enter properly toggles full screen.

+

*Individual control for sound channels! (See sound config for details).

+

*Undo/Redo Savestate/Loadstate features installed!  No more loss of data to unintentional presses.  (See getting started for details).

+

*Movie subtitles can now be included in .fm2 files.  See .fm2 documentation for details and Movie options for details on customizing.

+

*Auto-backup for movie files.  (See movie options for details).

+

*A Ram change monitor for the Memory watch dialog. (see memwatch for details).

+

*Frame counter works even without a movie loaded.

+

*AVI Directory Override option.

+


+

Major Bug / Crash Bug Fixes

+


+

*Fixed throttling problems that resulted on AMD Dualcore processors. (Caused FCEUX to appear to be in turbo mode).

+

*Fix major crash issue where NROM game (such as SMB) savestates were writing erroneous information if a non NROM game was loaded prior.

+

*Fixed a bug that caused a new sav file to not get created when loading a 2nd battery backed game.

+

*Fix Directory Overrides so to allow users to have no override.  Also fixes directory override reset bug.

+


+

Minor Bug fixes

+


+

*Hotkeys - prevent "Hotkey explosion" where some laptop keys set off all unassigned hotkeys

+

*Timing - "disable throttling when sound is off" now only affects FCEUX when sound is off

+

*Clip Left and Right sides taken into account when drawing on screen (record/play/pause, lag & frame counters, messages, etc)

+

*Fixed bug where having sound off and Mute turbo caused chirps when toggling

+

*Video settings - fixed bug when both aspect ratio correction and special scaling 3x are set, video was getting resized incorrectly

+

*Auto-save cleanup -prevent loading an auto-save from previous session.  Added flags for enabling auto-save menu item.

+

*Fixed issues related to big endian compiling. 

+

*Fix bug so that Escape can now be assigned as a hotkey

+

*Fixed bug in screenshot numbering that caused numbering to not reset when changing games.

+


+

GUI / Menu Enhancements

+


+

*A right-click context menu added!  Includes many commonly used items for a variety of situations.

+

*Menu items that are hotkey mappable now show their current hotkey mapping

+

*Major overhaul to the Menu organization.  

+

*All FCEUX features are now accessible in the menu

+

*Alt Menu Shortcuts properly configured

+

*Menu items are properly grayed when not useable

+

*All movie related menu items moved to a Movie options dialog 

+

*Removed hard-coded Accel keys and replaced with re-mappable hotkeys (Open & Close ROM)

+

*Drag & Drop for .fm2 and .lua files

+

*Many new functions added to the context menu (See context menu for details)

+

*New Mappable Hotkeys: Open Cheats, Open ROM, Close ROM, Undo/Redo savestate, Toggle Movie Subtitles

+


+

Lua

+


+

*Added input.get() !  Returns the mouse info and all keyboard buttons pressed by the user.

+

*Fixed joypad.set().  False now sets a button to off.  Nil does not affect the button at all (allowing the user to still control it).

+

*gui.text() Increased height (to approx. 7 lines).

+

*speedmode("turbo") now turns on turbo (which employs frame-skipping) rather than max speed.

+

*memory.readbyte will recognize frozen addresses (cheats).

+

*movie.framecount() always return a number, even when no movie is playing (since the frame counter is implemented without a movie loaded).

+

*Added FCEU.poweron()

+

*Added FCEU.softreset()

+

*Added FCEU.lagged()

+

*Added FCEU.lagcount()

+

*Added FCEU.getreadonly()

+

*Added FCEU.setreadonly()

+

*Added FCEU.fceu_setrenderplanes(sprites, background) 

+

*Added movie.active()

+

*Added movie.rerecordcount()

+

*Added movie.length()

+

*Added movie.getname()

+

*Added movie.playbeginning()

+

*Added -lua command line argment, loads a Lua script on startup

+

*Added zapper.read() - returns the zapper (mouse) data.  (Currently does return zapper data in movie playback).

+

*Added joypad.write and joypad.get for naming consistency. 

+

*Added rom.readbyte()

+

*Added rom.readbytesigned()

+


+

Sound Config

+


+

*Turning sound off disabled sound config controls

+

*Re-enabled sound buffer time slider control

+


+

Hex Editor

+


+

*Freezing ram addresses automatically updates the Cheats dialog if it is open.

+

* Added prevention from freezing more than 256 addresses at once (doing so caused crash bugs).

+

*Dialog remembers window size.

+

*Dump Rom & Dump PPU to file Dialogs use ROM to build default filename

+

*Maximize and minimize buttons added.

+

*Help menu item added

+


+

Memory Watch

+


+

*Dialog now includes Ram change monitoring. (see memwatch for details).

+

*Dialog is now collapsible to 1 column.

+

*No longer crashes when attempting to load an invalid file from the recent file menu.

+

*Cancel option added to the save changes dialog.

+

*Memory address values that are frozen by the debugger or hex editor are displayed in blue.

+

*Fixed bug that caused dialog to "disappear" due to saving -32000 as its window position.

+

*Save as dialog uses ROM name to build a default memory watch filename if there was no last used memory watch filename

+

*Drag and drop for .txt (memory watch) files.

+

*Minor menu and hotkey fixes.

+

*Watch values now compatible with custom windows dialog colors.

+


+

Debugger

+


+

*Shows scanlines and PPU pixel values

+

*Shows scanlines even while in VBlank

+

*Added a Run Line button (runs 1 scanline per click)

+

*Run 128 Lines button (runs 128 scanlines per click)

+

*Number of active cheats listed.

+

*Cheats list automatically updated if ram addresses are frozen in the hex editor.

+

*Fixed bug that caused dialog to "disappear" due to saving -32000 as its window position.

+

*Debugger now has a minimum valid size

+

*Added "Restore original window size" button

+


+

PPU Viewer 

+


+

*Default refresh value set to 15

+

*Refresh value stored in the .cfg file

+


+

Nametable Viewer

+


+

*Default refresh value set to 15

+

*Refresh value stored in the .cfg file

+


+

Trace Logger

+


+

*Fixed bug where user can't scroll the log window while it is auto-updating.

+

*Changed message about F2 pause (left over from FCEUXDSP) to display the current hotkey mapping.

+


+

Text Hooker

+


+

*Saving a .tht file no longer crashes

+

*Dialog updates every frame

+

*Initialization error checking reinstalled,

+

*Dialog remembers window position

+

*Fixed bug where canceling save as produces an error message.

+

*Save As produces default filename based on the current ROM

+


+

Message Log

+


+

*Remembers X,Y position

+

*Resized width and height

+

*Allowed more lines of text to appear on the screen at once.

+


+

Metadata

+


+

*Remembers window position

+

*Can be called from the context menu if a movie is loaded (see context menu for details).

+


+

TASEdit

+


+

*added help menu item

+

*disabled menu items that are not currently implemented.

+


+

Turbo

+

*Turbo now employs frame skip, greatly increasing its speed

+

*The mute turbo option completely bypasses sound processing (another big speed boost)

+

*Turbo now works with the Lazy wait for VBlank sync setting

+


+

SDL 

+

*SDL Movie subtitle support and subtitle toggle hotkey added.

+

*SDL Added fcm to fm2 converter tool to SDL version.

+

*SDL Improved the SDL sound code; drastically improves quality of sound.

+

*SDL Savestate slots are now mappable.

+

*SDL Major updates to SDL documentation

+

*SDL Added Shift+M for toggling automatic movie backups.

+

*SDL Added option to mute FCEUX for avi capturing, check the documentation for more details.

+

*SDL Added --noconfig command line option

+

*SDL Frame Advance Skip Lag frames toggle implemented

+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured EPub generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew211.html b/web/help/WhatsNew211.html index 73ada1ce..28918f02 100644 --- a/web/help/WhatsNew211.html +++ b/web/help/WhatsNew211.html @@ -1,156 +1,347 @@ - - + + + + + - What's New? 2.1.1 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.1.1 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.1.1 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.1.1

-

Released July 29, 2009

-


-

This release includes a multitude of new features, major fixes, and enhancements.

-


-


-

The 2.1 new release fixes some bugs of 2.1.0a, improves the accuracy of the sound core, and adds useability enhancements to the windows port.

-


-

Common - Bug fixes

- -


-

Improved Sound core/PPU

- -


-

NewPPU (still experimental, enabled by setting newppu 1 in the config file)

- -


-

Win32

-


-

Minor Bug fixes

- -


-


-

GUI/Enhancements

- -

   .fcm (autoconverts to .fm2 and begins movie playback)

-

   Savestates

-

   Palette files (.pal)

- -


-

SDL

-


- -


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free PDF documentation generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.1.1 (changelog)

+ +
+ +

+

What's New? 2.1.1

+

Released July 29, 2009

+


+

This release includes a multitude of new features, major fixes, and enhancements.

+


+


+

The 2.1 new release fixes some bugs of 2.1.0a, improves the accuracy of the sound core, and adds useability enhancements to the windows port.

+


+

Common - Bug fixes

+
    +
  • Fixed reported issue 2746924 (md5_asciistr() doesn't produce correct string)
  • +
  • Made default save slot 0 instead of 1
  • +
+


+

Improved Sound core/PPU

+
    +
  • Fixed the noise value, it seems that the noise logic was shifting the values to the left by 1 when reloading, but this doesn't work for PAL since one of the PAL reload value is odd, so fix the logic and used the old tables. Revert a stupid CPU ignore logic in PPU. Sorry about that. 
  • +
  • Updated with the correct values for the noise and DMC table, 
  • +
  • Fixed the CPU unofficial opcode ATX, ORing with correct constant $FF instead of $EE, as tested by blargg's. These fixes passes the IRQ flags test from blargg, and also one more  opcode test from blargg's cpu.nes test.
  • +
  • Square 1 & square 2 volume controls no longer backwards
  • +
  • Length counters for APU now correct variables
  • +
+


+

NewPPU (still experimental, enabled by setting newppu 1 in the config file)

+
    +
  • Added experimental $2004 reading support to play micro machines with (little) shakes, and fixed some timing in the new PPU.
  • +
  • Added palette reading cases for the new PPU.
  • +
+


+

Win32

+


+

Minor Bug fixes

+
    +
  • Replay movie dialog - Stop movie at frame x feature - fixed off by 1 error on the stop frame number
  • +
  • Hex Editor - changed ROM values again dsiplay as red, saved in the config as RomFreezeColor
  • +
  • Fixed bug in memory watch that would make the first watch value drawn in the wrong place if watch file was full
  • +
  • Debugger - Step type functions now update other dialogs such as ppu, nametable, code/data, trace logger, etc.
  • +
  • "Disable screen saver" gui option now also diables the monitor powersave
  • +
  • Recent menus - no longer crash if item no longer exists, instead it ask the user if they want to remove the item from the list
  • +
  • Sound Config Dialog - When sound is off, all controls are grayed out
  • +
  • Memory Watch - fixed a regression made in 2.0.1 that broke the Save As menu item
  • +
  • Memory Watch - save menu item is grayed if file hasn't changed
  • +
+


+


+

GUI/Enhancements

+
    +
  • Last save slot used is stored in the config file
  • +
  • Made fullscreen toggle (Alt+Enter) remappable
  • +
  • Hex editor - Reverted fixedFontHeight to 13 instead of 14.  Gave the option of adjusting the height by modifying RowHeightBorder in the .cfg file
  • +
  • Hex Editor - allowed the user to customize the color scheme by use of RGB values stored in the .cfg file
  • +
  • Hex editor - freeze/unfreeze ram addresses now causes the colors to update immediately, but only with groups of addresses highlighted at once (single ones still don't yet update)
  • +
  • Hex Editor - Save Rom As... menu option enabled and implemented
  • +
  • Window caption shows the name of the ROM loaded
  • +
  • Recent Movie Menu added
  • +
  • Load Last Movie context menu item added
  • +
  • Save Movie As... context menu item (for when a movie is loaded in read+write mode)
  • +
  • Drag & Drop support for all files related to FCEUX including:
  • +
+

    .fcm (autoconverts to .fm2 and begins movie playback)

+

    Savestates

+

    Palette files (.pal)

+
    +
  • Commandline - -palette commandline option
  • +
  • Memory Watch - option to bind to main window, if checked it gives GENS dialog style control, where there is no extra task bar item, and it minimizes when FCEUX is minimized
  • +
+


+

SDL

+


+
    +
  • added --subtitles
  • +
  • fixed Four Score movie playback
  • +
  • added --ripsubs for converting fm2 movie subtitles to an srt file
  • +
  • Lua is optional again, fixed the real issue
  • +
  • Lua is NO longer optional, so the SConscripts have been updated to reflect that change.  This fixes the mysterious non-working input issue.
  • +
  • implemented saving/loading a savestate from a specific file on Alt+S/L
  • +
  • implemented starting an FM2 movie on Alt+R
  • +
  • added --pauseframe to pause movie playback on frame x
  • +
  • dropped UTFConverter.c from SDL build
  • +
  • added hotkey Q for toggling read-only/read+write movie playback
  • +
+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Create help files for the Qt Help Framework

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew212.html b/web/help/WhatsNew212.html index e84e2ec0..70c8a22d 100644 --- a/web/help/WhatsNew212.html +++ b/web/help/WhatsNew212.html @@ -1,136 +1,327 @@ - - + + + + + - What's New? 2.1.2 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.1.2 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.1.2 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.1.2

-

Released November 3, 2009

-


-


-

The 2.1.2 release fixes some bugs of 2.1.0a, increases game compatibility, launches a new PPU core, and adds usability enhancements to the windows port.

-


-

Common

- -


-

Win32

-


- -


-

Minor Bug fixes

-


- -


-

Lua

- -


-


-

New Lua Scripts

- -


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create Help documents

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.1.2 (changelog)

+ +
+ +

+

What's New? 2.1.2

+

Released November 3, 2009

+


+


+

The 2.1.2 release fixes some bugs of 2.1.0a, increases game compatibility, launches a new PPU core, and adds usability enhancements to the windows port.

+


+

Common 

+
    +
  • New PPU is now functional!  You can access it by changing the newPPU flag in the config file.  Windows users can access it from Config > PPU > New PPU
  • +
  • Dragon Ball Z 3 now playable again
  • +
  • Fixed action 52 game that was broken in post-FCEUX 2.0.3 versions
  • +
  • Mapper 253 mostly implemented
  • +
  • Mapper 43 fixed bug
  • +
+


+

Win32

+


+
    +
  • Imported NSF features from FCEUXDSP-NSF.  Debugging tools are now compatible with NSF files.
  • +
  • Movies now record FDS disk swapping commands
  • +
  • Movie play dialog displays movie time based on ~60.1 (~50.1 PAL) instead of 60 & 50
  • +
  • Ram Watch and Ram Search dialogs imported from GENS rerecording
  • +
  • Ram Filter dialog removed (now redundant compared to both cheat search and ram search)
  • +
  • Lua script window ported from GENS
  • +
  • Fix for the directory overrides bug that caused overrides to reset
  • +
  • Debugger:  .deb file saving/loading restored
  • +
  • "Save config file" menu item
  • +
  • "New PPU" menu item
  • +
+


+

Minor Bug fixes

+


+
    +
  • Minor fixes to recent menus
  • +
  • Fixed a bug that prevented the Map Hotkeys dialog's X button from closing the dialog
  • +
  • Restored DPCM Logging when Code/Data Logger is active
  • +
  • Memory watch - Save Changes Prompt - clicking save will default to quicksave first and save as 2nd (instead of always defaulting to save as)
  • +
  • Made Trace Logger refresh adequately when using stepping options in the debugger.
  • +
+


+

Lua

+
    +
  • joypad.set() fixed.  True,False, and Nil now work properly for all buttons.  In addition there is a new "invert" option.
  • +
  • Lua5.1.dll no longer required to use lua.
  • +
  • fceu.unpause()
  • +
  • Added savestate.registerload(), savestate.registersave(), savestate.loadscriptdata()
  • +
  • emu. library, has all the same functions as fceu. library for better compatibility between lua emulators
  • +
  • Many additional function names to increase consistency with other lua emulators
  • +
  • Added movie.recording() and movie.playing()
  • +
  • Added memory.getregister() and memory.setregister()
  • +
  • Added gui.popup and input.popup
  • +
  • Added savestate.registerload(), savestate.registersave(), and savestate.loadscriptdata()
  • +
+


+


+

New Lua Scripts

+
    +
  • A multi-track movie recording tools written by FatRatKnight.  Allows input for different players to be recorded separately.
  • +
  • A rewinding tool by Antony Lavelle
  • +
+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free help authoring environment

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew213.html b/web/help/WhatsNew213.html index 60800a26..4e834e19 100644 --- a/web/help/WhatsNew213.html +++ b/web/help/WhatsNew213.html @@ -1,132 +1,323 @@ - - + + + + + - What's New? 2.1.3 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.1.3 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.1.3 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.1.3

-

Released April 8, 2010

-


-


-

The 2.1.3 release fixes some bugs of 2.1.2, increases game compatibility, and adds usability enhancements to the windows port and adds a GUI to the SDL port.

-


-

Common

- -


-

SDL

-


- -


-

Win32

-


- -


-

Lua

- -


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.1.3 (changelog)

+ +
+ +

+

What's New? 2.1.3

+

Released April 8, 2010

+


+


+

The 2.1.3 release fixes some bugs of 2.1.2, increases game compatibility, and adds usability enhancements to the windows port and adds a GUI to the SDL port.

+


+

Common 

+
    +
  • Fixed mappers 82, 25, 21, and 18.  Games such as SD Kiji Blader, Ganbare Goemon Gaiden, and Ganbare Goemon Gaiden 2, Jajamaru Gekimadden are now playable
  • +
  • Fixes for mappers 253 & 226 - fixes games such as Fire Emblem (J) and Fire Emblem Gaiden (J)
  • +
  • Fix crashing on game loading for any battery backed ROMs with mappers from MapInitTab (fixes Esper Dream 2 - Aratanaru Tatakai (J)
  • +
  • FDS - show name of missing bios file in error message
  • +
  • NewPPU - fixed sprite hit before 255 and for non transparent hits only, thanks to dwedit for providing the fix
  • +
  • .fm2 file format header now has an FDS flag
  • +
+


+

SDL

+


+
    +
  • A GUI!  A graphic user interface (using GTK) with many basic menu options
  • +
  • ported to SDL 1.3; compatibility maintained with 1.2
  • +
  • unix netplay is now functional; gtk network gui created
  • +
  • now prints the name of the mapper on ROM load
  • +
  • fixed dpad/joyhat support
  • +
  • VS unisystem keys now configable
  • +
  • changed default hotkeys and keys to match Win32
  • +
  • disallow --inputcfg gamepad0 and gamepad5
  • +
+


+

Win32

+


+
    +
  • Made savestate backups optional (config - enable - backup savestates)
  • +
  • Made savestate compression togglable (config - enable - compress savestates)
  • +
  • Cheats dialog - Pause while active checkbox
  • +
  • Cheats dialog - Toggling a cheat in the cheats list now updates the active cheats count
  • +
  • Debugger - added an auto-load feature
  • +
  • Debugger - Fix so it doesn't crash if unminimized with no game loaded 
  • +
  • Closing minimized windows no longer moves them the next time they get opened
  • +
  • Lua console - added a menu
  • +
  • Lua console - filename updates when lua scripts are dragged to emulator or recent filenames invoked
  • +
  • Name Table Viewer - Fix for use with New PPU
  • +
  • Trace Logger - Trace logger now logs the values of the stack pointer register
  • +
  • If a .fm2 file is drag and dropped with no ROM load, the open ROM dialog will appear
  • +
  • disable movie messages menu item
  • +
  • Added more window positions bounds checks. Accounts for -32000 positions and less out-of-range too
  • +
  • TASEdit - Added interface functionality (save/load, running TASEdit mid-movie, etc.)
  • +
+


+

Lua

+
    +
  • New lua functions: gui.parsecolor(), joypad.getup(), joypad.getdown(), emu.emulating()
  • +
  • Change gui.line, gui.box, joypad.get to function consistently with other lua emulators such as GENS rerecording
  • +
  • fixed zapper.read() to read movie data if a movie is playing.  Also changed the struct values to x,y,fire. This breaks lua scripts that used it previous, sorry
  • +
  • gui.text() now has out of bounds checking
  • +
  • Lua no longer unpauses the emulator when a script is loaded
  • +
+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured multi-format Help generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew214.html b/web/help/WhatsNew214.html index a499029a..ed515957 100644 --- a/web/help/WhatsNew214.html +++ b/web/help/WhatsNew214.html @@ -1,179 +1,370 @@ - - + + + + + - What's New? 2.1.4 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.1.4 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.1.4 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.1.4a

-

Released 01 June 2010

-

2.1.4 is a maintenance release that fixes these bugs in 2.1.4:

-

fix crash bug on .fcm convert

-

fix erroneous reporting of savestate past the end of movie error during read-only loadstates

-


-

Released 31 May 2010

-


-


-

The 2.1.4 release fixes many bugs and adds new features compared to 2.1.3. In addition it also fixes up the movie code significantly; fixing implementation problems, loading speed, adding new features, and fixing bugs.

-


-

Common

- -


-

Movies

-


- -


-

Lua

- -


-

New Lua functions

- -


-

Input Display

- -


-

Win32

- -


-

Debugger

-


- -


-

Hex Editor

-


- -


-

Cheat Search

-


- -


-

GUI

-


- -


-


-

-

Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.1.4 (changelog)

+ +
+ +

+

What's New? 2.1.4a

+

Released 01 June 2010

+

2.1.4 is a maintenance release that fixes these bugs in 2.1.4:

+

fix crash bug on .fcm convert

+

fix erroneous reporting of savestate past the end of movie error during read-only loadstates

+


+

Released 31 May 2010

+


+


+

The 2.1.4 release fixes many bugs and adds new features compared to 2.1.3. In addition it also fixes up the movie code significantly; fixing implementation problems, loading speed, adding new features, and fixing bugs. 

+


+

Common 

+
    +
  • Added microphone support option. When enabled, Port 2 Start activates the Microphone
  • +
  • Prevent .zip files containing no recognized files from causing crash
  • +
  • Autohold - Added player 3 and 4 to autohold notification window, labeled controller input
  • +
  • mapper 19 savestate fix mirroring for "Dream Master (J)" corrected to "four-screen" by CRC check
  • +
  • Disable auto-savestates during turbo 
  • +
  • Fixed so Gotcha! auto-enables the zapper
  • +
  • Autohold - Added player 3 and 4 to autohold notification window, labeled controller input
  • +
+


+

Movies

+


+
    +
  • Fully implemented "bulletproof" read-only
  • +
  • Movie code now fully conforms to the Savestate section of the Laws of TAS
  • +
  • Fixed a potential desync that plays out an extra frame without an update to the frame count involving heavy lua use, joypad.get, and a loadstate
  • +
  • Movie support for microphone
  • +
  • Movies now have a "finished" mode.  If a playback stops the movie isn't cleared from memory, and can be replayed or a state loaded Similar functionality as DeSmuME and GENS rerecording
  • +
  • New PPU flag in movie headers (doesn't change an emulators PPU state when loading a movie)
  • +
  • Much faster movie loading and movie-savestate loading
  • +
  • Made gamepad 2 off by default (so less movies should have unused player 2 data)
  • +
  • Implemented a "full savestate-movie load" mode similar to the implementation in VBA-rr and SNES9x-rr.  In this mode loading a savestate in read+write doesn't truncate the movie to its frame count immediately.  Instead it waits until input is recording into the movie (next frame).  For win32 this feature is togglable in movie options and the context menu.  For SDL this is off by default and a toggle will need to be added
  • +
  • Movie + loadstate errors are handled more gracefully now, with more informative error messages and the movie doesn't have to stop if backups are enabled
  • +
  • Fix PlayMovieFromBeginning when using a movie that starts from savestate
  • +
+


+

Lua

+
    +
  • fix bug that caused zapper.read() to crash when movie playback ends
  • +
  • Win32 - Added option for palette selection as color for LUA colors. Included is a LUA script to display all choices with the value used to pick displayed color
  • +
+


+

New Lua functions

+
    +
  • movie.ispoweron()
  • +
  • movie.isfromsavestate()
  • +
  • emu.addgamegenie()
  • +
  • emu.delgamegenie()
  • +
  • savestate.object() which is savestate.create() with intuitive numbering under windows
  • +
  • gui.getpixel() which gets any gui.pixel() set pixel colors, and possibly other functions
  • +
  • emu.getscreenpixel() which gets the RGB and Palette of any pixel on the screen
  • +
  • lua function movie.getfilename() which returns the current movie filename without the path included
  • +
+


+

Input Display

+
    +
  • Input display updates on loadstate
  • +
  • Input display overhaul that uses different colors for different input contexts
  • +
  • Input display now shows both currently pressed buttons and buttons held the previous frame
  • +
+


+

Win32

+
    +
  • Added NTSC 2x scalar option with some CFG config options of it's own Added Ram Search hotkeys for the first 6 search types in the list
  • +
  • Add Cheat buttons for Ram Search and Ram Watch
  • +
  • With special scaler in window mode, it's possible to resize to anything above the minimum.
  • +
  • Recording a new movie adds it to recent movies list
  • +
  • Replay dialog, when selecting a movie in a relative path (.\movies for example), the recent movies list stores an absolute path instead
  • +
  • Replay dialog shows PAL flag and New PPU flags
  • +
  • CDLogger - fixed bug preventing correct interrupt vectors from logging
  • +
  • Memwatch - ignore spaces at the beginnign of an address in the address boxes
  • +
  • Replay dialog - fix bug that was causing it to always report savestate movies as soft-reset
  • +
+


+

Debugger

+


+
    +
  • Added conditional debugging option 'K', for bank PC is on
  • +
  • Fixed bug involving pausing emulation outside of the debugger, then trying to use the debugger commands, and having the CPU registers become corrupted
  • +
  • Made debugger able to break on and distinguish Stack reads/writes
  • +
+


+

Hex Editor

+


+
    +
  • Added "Goto" command
  • +
  • Made the Hex Editor display the Frozen, Bookmarked, etc. status of the selected address, and made the Frozen color override the Bookmarked color.
  • +
+


+

Cheat Search

+


+
    +
  • Made enabling/disabling cheats no longer deselect the selected cheat
  • +
  • Added context menu to Cheat Dialog Cheat Listbox, populated list with Toggle Cheat, Poke Cheat Value, and Goto In Hex Editor
  • +
  • Enabled multi-select for Cheat menu to allow multiple toggles and deletes
  • +
  • Made cheat menu's Pause When Active effect immediate
  • +
+


+

GUI

+


+
    +
  • Added Tools - GUI option to partially disable visual themes, so the emulator can be made to look like it did in 2.1.1 and earlier releases. Drag & Drop - if dropping a .fcm with no ROM loaded, prompt for one (same functionality that was added to .fm2 files)
  • +
  • Added single-instance mode, which makes starting a second copy of FCEUX load the file into the first, then exit.Mode off by default, togglable under Config - GUI
  • +
+


+


+

+

Created with the Personal Edition of HelpNDoc: Produce electronic books easily

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew215.html b/web/help/WhatsNew215.html index 49a05aae..199240c1 100644 --- a/web/help/WhatsNew215.html +++ b/web/help/WhatsNew215.html @@ -1,148 +1,339 @@ - - + + + + + - What's New? 2.1.5 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.1.5 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.1.5 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.1.5

-

Released 04 June 2011

-


-


-

The 2.1.5 release fixes a lot of bugs and brings various improvements to the prior 2.1.4a release. In addition, the SDL port has improved signficantly; completely overhauling the GTK2 GUI, fixing many sound issues, and fixing a variety of bugs.

-


-

Common

- -


-

Movies

-


- -


-

Lua

- -


-

New Lua functions

- -


-

Win32

- -


-

Debugger

-


- -


-

Hex Editor

-


- -


-

Ram Watch / Ram Search

-


- -


-

TasEdit

-


- -


-

GUI

-


- -


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free help authoring tool

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.1.5 (changelog)

+ +
+ +

+

What's New? 2.1.5

+

Released 04 June 2011

+


+


+

The 2.1.5 release fixes a lot of bugs and brings various improvements to the prior 2.1.4a release. In addition, the SDL port has improved signficantly; completely overhauling the GTK2 GUI, fixing many sound issues, and fixing a variety of bugs.

+


+

Common 

+
    +
  • Fixed compatibility issue with Young Indiana Jones Chronicles
  • +
  • Fixed bug in new PPU that made some intensify bits not get applied to output (fixed flashing siren screen in Werefolf)
  • +
  • Fix many segmentation faults related to file handling
  • +
+


+

Movies

+


+
    +
  • Slight performance increase when loading movies
  • +
  • Fixed read-only loadstate error messages and logic
  • +
+


+

Lua

+
    +
  • Lua socket added to built-in lua library
  • +
  • Fixed speed.mode() function so that normal turns off turbo
  • +
+


+

New Lua functions

+
    +
  • gui.savescreenshotas()
  • +
  • sound.get()
  • +
+


+

Win32

+
    +
  • Fixed bug where PPU toggling toggled the Game Genie as well
  • +
  • Fixed some minor GUI issues
  • +
  • Added avi capture commandline argument and related parameters
  • +
  • Fix input selection for Famicom Expansion port
  • +
+


+

Debugger

+


+
    +
  • Fixed Ram Search to only display valid RAM addresses (0000-07FF and 6000-7FFF)
  • +
  • Fixed crash when re-opening debugging window
  • +
+


+

Hex Editor

+


+
    +
  • Added a confirmation prompt before removing all bookmarks
  • +
+


+

Ram Watch / Ram Search

+


+
    +
  • Fixed the multiple selection of watches
  • +
  • Added support for Multiple selection of addresses in RamWatch Fixed issue with restoration of the selection range in RamWatch
  • +
+


+

TasEdit

+


+
    +
  • General cleanup
  • +
  • Fixed crash when truncating while turbo was enabled
  • +
  • Invalidate greenzone when re-recording earlier portions of a movie
  • +
+


+

GUI

+


+
    +
  • Added "SaveStateAs" menu item
  • +
  • Display movie name at the top of the main window
  • +
+


+


+


+

+

Created with the Personal Edition of HelpNDoc: iPhone web sites made easy

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew220.html b/web/help/WhatsNew220.html index d5d167a6..1a87cbcb 100644 --- a/web/help/WhatsNew220.html +++ b/web/help/WhatsNew220.html @@ -1,252 +1,443 @@ - - + + + + + - What's New? 2.2.0 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.2.0 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.2.0 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.2.0

-

Released -- 27 November 2012

-


-


-

The 2.2.0 release fixes a lot of bugs and adds many new features to prior releases, increasing game compatibility and enhancing usability of both Windows and SDL ports. The Windows version also includes major improvement of debugging tools and introduces the new powerful toolset – TAS Editor v1.0 – created to boost efficiency and ease of Tool-Assisted Speedrunning.

-


-

Common

- -


-

Emulation

- -


-

Movies

- -


-

Lua

- -


-

New Lua functions:

- -


-

New scripts:

- -


-

Win32

- -


-

TAS Editor

- -


-

Debugger

- -


-

Trace Logger

- -


-

Code/Data Logger

- -


-

Hex Editor

- -


-

RAM Watch / RAM Search

- -


-

Cheats

- -


-

SDL

- -


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Free Web Help generator

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.2.0 (changelog)

+ +
+ +

+

What's New? 2.2.0

+

Released -- 27 November 2012

+


+


+

The 2.2.0 release fixes a lot of bugs and adds many new features to prior releases, increasing game compatibility and enhancing usability of both Windows and SDL ports. The Windows version also includes major improvement of debugging tools and introduces the new powerful toolset – TAS Editor v1.0 – created to boost efficiency and ease of Tool-Assisted Speedrunning.

+


+

Common 

+
    +
  • Fixed crash when using machine with no sound card
  • +
  • Fixed long savestate messages containing path
  • +
  • Soft reset and power switch messages
  • +
  • All onscreen messages are now logged to Message Log
  • +
  • Fixed wrong default palette entry
  • +
  • Fixed bug when loading UNIF games
  • +
  • Improved HUD text rendering wrapping
  • +
  • "Display FPS" option
  • +
+


+

Emulation

+
    +
  • PAL/NTSC noise channel bug fixed
  • +
  • All latest mapper changes from fceu-mm
  • +
  • Also added mappers 176, 116, 156, 252, 28
  • +
  • Fixed mappers 242, 227, 115, 248, 12, 164, 15, 253, 23, 178, 90, 73 and many others
  • +
  • Straighten out bandai m159/m016 handling and add valid null-EEPROM emulation to get those games booting.
  • +
  • Add ability for CNROM games to choose whether they have bus conflicts (fixes Colorful Dragon (Unl) (Sachen), since it flakes out if bus conflicts are emulated)
  • +
  • Fixed bus conflict emulation, no kage no densetsu bug anymore
  • +
  • Fixed newppu bug which prevented metroid from booting, CHR RAM was not getting initialized to anything
  • +
  • Newppu - fix bug in scroll reg logic causing mis-scrolls in p'radikus conflict
  • +
+


+

Movies

+
    +
  • Fixed old bug in "Play Movie From Beginning"
  • +
  • Fixed replay engine bug that doubles the last input of the movie
  • +
  • Fixed movie savestates logic, loading post-movie savestates from different timeline is not allowed in read-only
  • +
  • Fixed savestates filenaming bug when working with a movie
  • +
  • Added support for HUD recording in AVI dumping
  • +
  • Rerecords counter display
  • +
  • Config->Movie options->Always suggest Read-Only replay (for Replay dialog). No more accidental rewrites!
  • +
  • Removed "Lag Counter Reset" hotkey, as it was obsolete since FCEUX 2.0.2
  • +
+


+

Lua

+
    +
  • Fixed lua drawing alpha blending
  • +
  • Auto-clearing previous frame drawings (same behaviour as other emulators)
  • +
  • New library: taseditor (Windows-only) - contains 24 functions, see taseditor.chm
  • +
+


+

New Lua functions:

+
    +
  • emu.paused()
  • +
  • emu.setlagflag()
  • +
  • joypad.getimmediate()
  • +
+


+

New scripts:

+
    +
  • BoulderDash_AmoebaAI.lua
  • +
  • ButtonCount.lua
  • +
  • CustomLagIndicator_RvT.lua
  • +
  • RBIBaseball.lua
  • +
  • SoundDisplay.lua
  • +
  • SoundDisplay2.lua
  • +
  • taseditor\InputDisplay_for_Selection.lua
  • +
  • taseditor\InvertSelection.lua
  • +
  • taseditor\RecordBackwards.lua
  • +
  • taseditor\ShowNotes.lua
  • +
  • taseditor\Swap1P2P.lua
  • +
  • taseditor\TrackNoise.lua
  • +
+


+

Win32

+
    +
  • Total revamp of fulscreen support
  • +
  • Fixed graphic tearing with vertical sync enabled
  • +
  • Added "Maintain aspect ratio" option to Video config
  • +
  • Added "Hide mouse cursor" and "Use console BG color for empty areas" options to Video config
  • +
  • Added "Switch fullscreen by double-click" option to GUI config
  • +
  • Added "Force Grayscale" option to Palette config
  • +
  • Fixed crashes and bugs caused by 2.1.5 allowing hotkeys without ROM loaded
  • +
  • Lua console now gets proper file path when selecting a file from the recent menu
  • +
  • Fixed context menus to use rightclicks in context menus correctly
  • +
  • Reload hotkey now also supports removing invalid filenames in Recent ROMs
  • +
  • Replay dialog speedup, it doesn't search for movies in fceux root folder anymore
  • +
  • Support multibyte languages for opening files through drag&drop (except for Lua files)
  • +
  • Loading TAS Editor projects (*.fm3) by drag&drop
  • +
  • Fixed bug with Input Config not displaying some key names
  • +
  • Launch tools hotkeys shown in menu; general cleanup of menu/settings, changed some checkboxes to radiobuttons
  • +
  • Added "Clear" button to Message Log
  • +
+


+

TAS Editor

+
    +
  • Completely rewritten tool with brand new architecture and design. Too many changes to enlist, see taseditor.chm
  • +
+


+

Debugger

+
    +
  • General window layout cleanup; different font; ".DEB files" can be switched off; etc
  • +
  • Deleting a breakpoint/bookmark leaves selection in the list
  • +
  • Fixed mysterious out of bounds condition while editing breakpoints
  • +
  • Fixed RAM peek by a rightclick on left pane
  • +
  • Allow Frame Advancing when Debugger is in breakpoint state
  • +
  • Disabled breakpoints now don't impose slowdown
  • +
  • When a breakpoint is hit, it becomes highlighed (selected) in the breakpoints list
  • +
  • Show the number of breakpoints (enabled and total) above the breakpoints list
  • +
  • ">" points at current line in disassembly
  • +
  • Improved stack display
  • +
  • Added "CPU cycles" and "Instructions" counters (cumulative and delta)
  • +
  • Added "Cycles counter exceeds N" and "Instructions counter exceeds N" type of breakpoints
  • +
  • Single click on any address copies this address to the "Seek To" field and "Bookmark Add" field
  • +
  • Double-click on any address prompts "Add Breakpoint here" dialog
  • +
  • "ROM offsets" option displays real ROM addresses in the Disassembly window
  • +
  • Fixed conditional breakpoints bug: the error message didn't appear when editing a breakpoint
  • +
  • Fixed and improved Symbolic debug (Names and Comments display)
  • +
  • Added Bookmarks naming
  • +
  • Cleaned up and vastly improved debugging documentation
  • +
+


+

Trace Logger

+
    +
  • Added "Symbolic trace" option
  • +
  • "RTS" instructions now output the subroutine address/name
  • +
  • Added "Use Stack Pointer for code tabbing (nesting visualization)" option
  • +
  • Added "To the left from disassembly text" option for log format customization
  • +
  • Added "Log current Frame number" option
  • +
  • Added "Log emulator messages" option
  • +
  • Added "Log breakpoint hits" option
  • +
  • Fixed bug with trying to log to file without choosing a filename
  • +
  • Tracer now also updates its window when user pauses the game, not just when Debugger snaps
  • +
+


+

Code/Data Logger

+
    +
  • Now can log data access from RAM code
  • +
  • "Save Unused Data" button complements "Save Stripped iNes Rom" feature
  • +
  • Now can log VROM access (CHR banks of the ROM) when NewPPU is enabled
  • +
+


+

Hex Editor

+
    +
  • Display 0x5000-0x5FFF contents
  • +
  • Ctrl+F opens Find dialog
  • +
+


+

RAM Watch / RAM Search

+
    +
  • Updating list when emulator is paused (on Power or when resetting search)
  • +
  • Fixed loading Data Size and Data Type from a .wch, now corrupted .wch won't crash
  • +
+


+

Cheats

+
    +
  • Added Compare box to the Cheats window
  • +
  • Don't lose cheat compare value when toggle cheat enables through UI
  • +
  • Parse cheat files with non-ASCII characters properly
  • +
+


+

SDL

+
    +
  • gtk 2.24 now recommended
  • +
  • added gtk hotkey configuration dialog
  • +
  • updated/added various gui elements for options
  • +
  • new option: SDL.ShowFPS
  • +
  • new option: SDL.Input..EnableOppositeDirectional - allow/disallow simultaneous right+left/up+down input
  • +
  • fixed various build issues
  • +
  • fixed segfault occuring during particular sequences in the cheat menu
  • +
  • fixed potential segfault with gui
  • +
  • fixed segfault issue on debian/ubuntu with proprietary nvidia drivers
  • +
  • now compatible with llvm/clang++ 
  • +
  • added build option to dynamically link lua
  • +
  • updated default server configuration file to "fceux-server.conf" (from "fceu-server.conf")
  • +
  • updated manpage and documentation
  • +
+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew221.html b/web/help/WhatsNew221.html index 34349f41..0ab617c7 100644 --- a/web/help/WhatsNew221.html +++ b/web/help/WhatsNew221.html @@ -1,186 +1,377 @@ - - + + + + + - What's New? 2.2.1 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.2.1 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.2.1 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.2.1

-

Released -- 10 March 2013

-


-


-

The 2.2.1 release fixes many bugs and adds a couple of new features. The most notable feature is "Auto-resume old play session", which is similar to "Suspending Play". Enable this option in the Config menu and now you can close ROMs or emulator anytime, next time the game state will be resumed from the closing point.

-


-

Common

- -


-

Emulation

- -


-

Lua

- -


-

New Lua functions:

- -


-

New scripts:

- -


-

Win32

- -


-

TAS Editor

- -


-

Trace Logger

- -


-

Code/Data Logger

- -


-

Hex Editor

- -


-

RAM Search

- -


-

Cheats

- -


-

SDL

- -


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Easy CHM and documentation editor

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.2.1 (changelog)

+ +
+ +

+

What's New? 2.2.1

+

Released -- 10 March 2013

+


+


+

The 2.2.1 release fixes many bugs and adds a couple of new features. The most notable feature is "Auto-resume old play session", which is similar to "Suspending Play". Enable this option in the Config menu and now you can close ROMs or emulator anytime, next time the game state will be resumed from the closing point.

+


+

Common 

+
    +
  • Speed up HUD text drawing
  • +
+


+

Emulation

+
    +
  • Finished mappers to boards conversion
  • +
  • Fixed mappers 99, 228, 18, 198, 24, 26, 69, 19
  • +
  • Mapper 115 - redesign according to the hardware tests
  • +
  • Fixed "you ling xing dong" by assigning to mapper 192
  • +
  • Fixed crash when four-screen bit is set after CRC check
  • +
  • UNIF: verbose/safe chunk loading, fixes some crashes
  • +
+


+

Lua

+
    +
  • removed "shadow pixels" from gui.text()
  • +
+


+

New Lua functions:

+
    +
  • gui.parsecolor()
  • +
+


+

New scripts:

+
    +
  • JumpingFCEUXWindow.lua
  • +
+


+

Win32

+
    +
  • Fixed "Enter New Input" dialog (Hotkeys mapping)
  • +
  • Fixed zapper and mouse positioning in fullscreen
  • +
  • Remodel "Video config" dialog
  • +
  • Added "TV Aspect (4:3)"
  • +
  • Holding Shift when resizing FCEUX window inverts "Force integral factors" meaning
  • +
  • Fixed window regions redrawing
  • +
  • Added the option to define custom emulation speed (NES->Emulation Speed->Set Custom Speed)
  • +
  • Now Frame Advance timings (initial delay and speed) can be tweaked by user
  • +
  • Added Config->Enable->Auto-resume old play session
  • +
  • Moved "Config->Game Genie" to "Config->Enable->Game Genie ROM"
  • +
  • Play movie dialog shows New PPU in red if the required setting does not match
  • +
  • Fixed NameTable Viewer crash when the corresponding nametable RAM is not available on the cart
  • +
  • The number of active cheats is displayed on screen when a ROM is loaded
  • +
  • PPU/PAL/Input type changing is disabled when a movie is playing
  • +
+


+

TAS Editor

+
    +
  • Fixed keyboard accelerators when editing Notes
  • +
  • Fixed Greenzone saving while emulator is unpaused
  • +
  • Fixed drawing bugs when the Playback cursor moves more than once within one update
  • +
  • Changed "Compact save" dialog, added 4 options of Greenzone saving
  • +
  • Added "Config->Project file saving options"
  • +
  • Changed "Follow cursor" logic, now the Piano Roll doesn't follow Playback cursor while seeking
  • +
  • No "Autopause at the end of the Movie" when Recording
  • +
  • Fixed bug when adding new item to History Log
  • +
  • Fixed Bookmarks List height on Windows 7
  • +
+


+

Trace Logger

+
    +
  • Fixed RAM-located code logging when CDLogger options are enabled
  • +
  • Fixed automatic window update when a breakpoint is hit
  • +
  • Fixed RTS padding
  • +
+


+

Code/Data Logger

+
    +
  • Added current CDL filename field and default CDL naming
  • +
  • Added "Auto-save .CDL when closing ROMs" option
  • +
  • Added "Auto-load .CDL when opening the window" option
  • +
  • Added "Auto-resume logging when loading ROMs" option
  • +
  • Improved CHR logging, now it also logs the data when using Old PPU
  • +
+


+

Hex Editor

+
    +
  • Show symbolic names in the window caption when "Symbolic debug" is enabled
  • +
  • Fixed crash when trying to save ROM to an invalid path
  • +
  • Fixed ROM coloring when using CDLogger data
  • +
+


+

RAM Search

+
    +
  • Added "Search ROM" option
  • +
+


+

Cheats

+
    +
  • Added "Add from CHT file..." button
  • +
  • Update the list of cheats when ROM is changed
  • +
+


+

SDL

+
    +
  • Use desktop resolution for fullscreen by setting SDL.XResolution and SDL.YResolution to 0 (new default is 0)
  • +
  • Fixed bug where "quit" hotkey would do nothing in '--nogui' mode
  • +
  • Fixed fullscreen zapper issues
  • +
  • Display a message dialog on errors in addition to printing to stderr
  • +
  • Added "Options->Auto-Resume Play"
  • +
  • Fixed build issues on various versions of OS X
  • +
+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Full-featured EBook editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew222.html b/web/help/WhatsNew222.html index 34419719..f6689ba3 100644 --- a/web/help/WhatsNew222.html +++ b/web/help/WhatsNew222.html @@ -1,195 +1,386 @@ - - + + + + + - What's New? 2.2.2 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.2.2 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.2.2 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.2.2

-

Released -- 23 September 2013

-


-


-

The 2.2.2 release fixes a number of emulation bugs and adds many new features, most of which are related to debugging and reverse engineering.

-


-

Common

- -


-

Emulation

- -


-

Lua

- -


-

New Lua functions:

- -


-

Win32

- -


-

TAS Editor

- -


-

Debugger

- -


-

Trace Logger

- -


-

PPU Viewer

- -


-

Hex Editor

- -


-

RAM Search/RAM Watch

- -


-

SDL

- -


-


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Generate EPub eBooks with ease

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.2.2 (changelog)

+ +
+ +

+

What's New? 2.2.2

+

Released -- 23 September 2013

+


+


+

The 2.2.2 release fixes a number of emulation bugs and adds many new features, most of which are related to debugging and reverse engineering.

+


+

Common 

+
    +
  • Properly savestate NSF files
  • +
  • "Auto-resume old play session" now also works with NSFs
  • +
+


+

Emulation

+
    +
  • Fixed mappers 178, 28, 53, 154, 43, 253, 19, 2
  • +
  • Mapper 012 - added hardware dip for language select
  • +
  • UNIF PEC-586 - fixed render, added 512K cartridges suppport
  • +
  • Fixed UNIF 8157, UNIF T-262, UNIF DANCE2000
  • +
  • Palette RAM reading fix for Old PPU
  • +
  • Bring some improvements to New PPU from BizHawk, fix vtoggle5/6 back to vtoggle
  • +
  • Fixed mmc5 savestates
  • +
+


+

Lua

+
    +
  • Fix wrong frequency calculation in sound.get() function
  • +
+


+

New Lua functions:

+
    +
  • tobitstring()
  • +
  • memory.readword()
  • +
  • memory.readwordsigned()
  • +
  • debugger.hitbreakpoint()
  • +
  • debugger.getcyclescount()
  • +
  • debugger.getinstructionscount()
  • +
  • debugger.resetcyclescount()
  • +
  • debugger.resetinstructionscount()
  • +
+


+

Win32

+
    +
  • Added "Square pixels" option to Video Config
  • +
  • "TV Aspect" ratio can be customized, by default it's 4:3
  • +
  • Changed "Disable hardware acceleration" checkbox to a drop-down list with 3 options
  • +
  • Movie recording: remember last Author name when creating a new movie
  • +
  • Movie recording: added ability to record "Insert coin" command (for VS games)
  • +
  • When no script is currently running, Shift+L loads the most recent Lua script
  • +
  • Dynamic link to lua51.dll instead of static linking, because some external libraries might crash without lua51.dll
  • +
  • Updated 7z.dll to v9.22
  • +
  • A couple of fixes which deal with "multiple ROMs in a single archive" case
  • +
  • Auto-disable "Game Genie ROM" feature when no "gg.rom" file is found
  • +
  • Fixed "Single Instance Mode"
  • +
+


+

TAS Editor

+
    +
  • Comply with Lua movie.rerecordcounting() setting
  • +
  • Fixed workflow with "Auto-adjust Input according to Lag" disabled
  • +
+


+

Debugger

+
    +
  • Smart scrolling up/down by whole instructions - ported from an obscure version of FCEUXD 1.1
  • +
  • Scrolling maintains relative position of the ">" pointer inside the Disassembly window
  • +
  • Highlight PC pointer line when a breakpoint is hit
  • +
  • debuggerFontSize can be specified in fceux.cfg
  • +
  • Fixed storing and loading .deb files when working with archived ROMs
  • +
  • Fixed Cycles counter reset when loading an earlier savestate
  • +
  • Added Symbolic Debug naming by right-clicking any address or name
  • +
  • Symbolic names behave the same way as usual addresses
  • +
  • Newly created Bookmarks inherit existing symbolic name by default
  • +
  • Added CDL data column to the left from Disassembly, to distinguish executed branches of code from not executed
  • +
  • Added 'T' condition for breakpoints (it checks the bank of the accessed data, see docs)
  • +
+


+

Trace Logger

+
    +
  • The dialog window can be resized
  • +
  • Do not clear window log when stopping the logging
  • +
  • Added "Log Cycles count" and "Log Instructions count" options
  • +
  • Added Symbolic Debug naming by right-clicking any address or name
  • +
  • Clicking any address select the address
  • +
  • Double-clicking any address brings Debugger at the address
  • +
  • Added mouse wheel support
  • +
  • Only output "from $XXXX" when the subroutine was called by JSR
  • +
+


+

PPU Viewer

+
    +
  • Added "Mask unused graphics" feature (needs Code/Data Logger running)
  • +
  • Fixed window layout when using big fonts
  • +
+


+

Hex Editor

+
    +
  • Added "Highlighting" submenu and "Highlight Activity" feature
  • +
  • Added Symbolic Debug naming by right-clicking any address
  • +
  • Specify Data bank condition when adding a Breakpoint by context menu
  • +
  • Fixed bugs when saving files while working with ROMs in archives
  • +
  • hexeditorFontSize can be specified in fceux.cfg
  • +
+


+

RAM Search/RAM Watch

+
    +
  • Added "Hex Editor" button to RAM Search (right-clicking an address works as well)
  • +
  • Fixed RAM Watch bug when contents of old .wch file were mixed with the newly saved data
  • +
+


+

SDL

+
    +
  • "--periodicsaves" command line option
  • +
  • "--4buttonexit" command line option
  • +
  • "--loadstate X" and "--savestate X" command line options
  • +
  • Added Unity desktop support
  • +
  • Added otion to use system-provided LUA library instead of statically linked LUA
  • +
  • Fix issue where battery backup save was not being saved when using "Quit" hotkey
  • +
  • Fixed bug where FCEUX would take exclusive grab of input in windowed mode when resuming from pause
  • +
+


+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Easily create EBooks

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/WhatsNew223.html b/web/help/WhatsNew223.html index 860fa1e0..906899ec 100644 --- a/web/help/WhatsNew223.html +++ b/web/help/WhatsNew223.html @@ -1,208 +1,399 @@ - - + + + + + - What's New? 2.2.3 (changelog) - - - - - - - - - - + + + + + + + + What's New? 2.2.3 (changelog) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

What's New? 2.2.3 (changelog)

- -
- Introduction ››
-
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

What's New? 2.2.3

-

Released -- 28 July 2016

-


-


-

The 2.2.3 release fixes a number of emulation bugs, features overclocking (for lag reduction) and Dendy mode, and adds support for a bunch of new ROM dumps (mostly unlicensed). Reverse engineering tools and Lua scripting have got some updates, new input devices are supported, new palette files have beed added. The SDL port has been fixed and updated as well.

-


-

Common

- -


-

Emulation

- -


-

Movies

- -


-

Video

- -


-

Palette

- -


-

Sound

- -


-

Input

- -


-

Lua

- -


-

New Lua functions:

- -


-

Win32

- -


-

Debugger

- -


-

Trace Logger

- -


-

Symbolic debugging

- -


-

CDLogger

- -


-

PPU Viewer

- -


-

Hex Editor

- -


-

Cheats

- -


-

SDL

- -


-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Easily create Web Help sites

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

What's New? 2.2.3 (changelog)

+ +
+ +

+

What's New? 2.2.3

+

Released -- 28 July 2016

+


+


+

The 2.2.3 release fixes a number of emulation bugs, features overclocking (for lag reduction) and Dendy mode, and adds support for a bunch of new ROM dumps (mostly unlicensed). Reverse engineering tools and Lua scripting have got some updates, new input devices are supported, new palette files have beed added. The SDL port has been fixed and updated as well.

+


+

Common

+
    +
  • Customizable overclocking
  • +
  • Dendy mode
  • +
  • Fixed rerecord counting broken outside taseditor
  • +
+


+

Emulation

+
    +
  • Added mappers: 29, 30, 
  • +
  • Fixed mappers: 225, 119, 4, 35, 31, 69, 212, 45, 
  • +
  • Fixed mmc5 IRQ handling
  • +
  • Fixed mmc1 reg#3 masking
  • +
  • Fixed vrc7 sound savestates
  • +
  • Added CoolBoy, KS7010, SB200, UNIF 158B, UNIF DRAGONFIGHTER, UNIF BMC-10-24-C-A1, UNIF EH8813A, UNIF HP898F, UNIF F-15, UNIF RT-01, UNIF UNL-KS7017, UNIF BMC-81-01-31-C, UNIF UNL-8-IN-1
  • +
  • NES 2.0 support
  • +
  • Fixed UNIF BMC 12 IN 1, UNIF OneBus
  • +
+


+

Movies

+
    +
  • Fixed a bug with FDS flag being always set when converting a FCM
  • +
+


+

Video

+
    +
  • Prescale filter for 2x, 3x and 4x resolutions
  • +
  • Made NTSC filter internal resolution closer to 4:3
  • +
+


+

Palette

+
    +
  • Support 512 color palettes
  • +
  • Added external palettes: SONY_CXA2025AS_US.pal, RP2C03.pal (and its versions), Unsaturated-V6.pal
  • +
  • Option to swap deemphasis bits
  • +
+


+

Sound

+
    +
  • Option to swap duty cycles
  • +
  • NSF can be set to Dendy mode
  • +
+


+

Input

+
    +
  • Fix Mouse input implementation
  • +
  • Support for SNES mouse
  • +
  • PEC-586 russian keyboard support
  • +
+


+

Lua

+
    +
  • Removed speed notification per script reload, if it remained 100%
  • +
  • Fixed lua drawings in NSF
  • +
  • Proper halo for lua font
  • +
  • Fixes to sound.get() region consistency and frequency/midikey detection for Noise and DPCM channels
  • +
+


+

New Lua functions:

+
    +
  • emu.getpath()
  • +
  • emu.loadrom()
  • +
  • rom.writebyte()
  • +
  • gethash()
  • +
+


+

Win32

+
    +
  • Added -dumpinput and -playinput functions
  • +
  • Support for SNES pad
  • +
  • Added onscreen messages when region changes
  • +
+


+

Debugger

+
    +
  • Added debuggerPageSize config variable which lets you pick whether 8KB physical PRG pages are used, or 16KB (the original). It defaults to 14 (1<<14 == 16KB).
  • +
  • Set symbolic debugger name entry dialog text limits when creating a new label
  • +
  • Fixed new-PPU debug information (address and pixel)
  • +
  • Step Into hotkey
  • +
  • More granular accounting of scanline and dot
  • +
+


+

Trace Logger

+
    +
  • Fixed incorrect display of resolved address for (FF,x)
  • +
+


+

Symbolic debugging

+
    +
  • Optionally display register names
  • +
+


+

CDLogger

+
    +
  • Fix crash when attempting to open file picked as target for Save Stripped ROM operation
  • +
+


+

PPU Viewer

+
    +
  • 8x16 sprite display mode
  • +
+


+

Hex Editor

+
    +
  • Added option to dump entire 64k memory space
  • +
  • Don't forget to load the symbols, when hex editor is first launched before debugger
  • +
  • Show values for registers $4000-$4017
  • +
+


+

Cheats

+
    +
  • mmc5 Akumajou Dracula crash fix
  • +
  • More RAM available in search
  • +
+


+

SDL

+
    +
  • Added apply button to video config dialog
  • +
  • Added link to libgd project download page in readme
  • +
  • Noted optional libgd dependency in readme
  • +
  • SCons: Fixed logic for LOGO and CREATE_AVI options
  • +
  • Manpage updates
  • +
  • Added hotkeys for volume up/down
  • +
  • Menu toggling with the Alt key
  • +
  • Print error when opengl/scalers are both enabled
  • +
  • Fixed bug where lua open file gui would default to home directory
  • +
+


+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Benefits of a Help Authoring Tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/_keywords.json b/web/help/_keywords.json new file mode 100644 index 00000000..ea749ce8 --- /dev/null +++ b/web/help/_keywords.json @@ -0,0 +1 @@ +[{ "id": "C1B680E8F62941B9A3545C40D55C8D92", "parent" : "#", "text": "\"Can't find FDS Bios image when I attempt to load a .fds game!\"", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "3A9A6DF0D6944C2F863A69AF188FFD9E", "parent" : "#", "text": "\"Directdraw: Error creating secondary surface\"", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "2DC461B98AA940439B3E3BF1AF8A3A17", "parent" : "#", "text": "2C02 PPU memory map", "a_attr": {"href": "NESRAMMappingFindingValues.html", "data-related": "[]"} },{ "id": "9101D638E01D45678C3EC7B34E5A6FC2", "parent" : "#", "text": "Alternate A and B", "a_attr": {"href": "AutoFireConfigurations.html", "data-related": "[]"} },{ "id": "ECFDE454CB5D4FA0B4BD610C7C200E0A", "parent" : "#", "text": "Arkanoid Paddle", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "348CDF1BAD4B427BBEEBBA1F1FCB90A0", "parent" : "#", "text": "Autofire Offset", "a_attr": {"href": "AutoFireConfigurations.html", "data-related": "[]"} },{ "id": "F1C81D7111184882A0A4979B09375D32", "parent" : "#", "text": "Autofire Pattern", "a_attr": {"href": "AutoFireConfigurations.html", "data-related": "[]"} },{ "id": "4683F51E46514ED0902131C1EF8CE048", "parent" : "#", "text": "Auto-Hold", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "81EDD86C638C458CAD8A2BFCB3DA0C35", "parent" : "#", "text": "Basic Bot", "a_attr": {"href": "#", "data-related": "[]"} },{ "id": "ACB5D74040B04AFE99CE2687D3BAA500", "parent" : "#", "text": "Capturing a Movie File", "a_attr": {"href": "AVICapturing.html", "data-related": "[]"} },{ "id": "08E1D7750E3B44DE87E739E6D8D66829", "parent" : "#", "text": "Cheat Guide", "a_attr": {"href": "CheatSearch.html", "data-related": "[]"} },{ "id": "C3BE991088FA44B590B0511384EF6B8C", "parent" : "#", "text": "Code/Data Logger", "a_attr": {"href": "CodeDataLogger.html", "data-related": "[]"} },{ "id": "95B1FE614C174C988D86A0168461B139", "parent" : "#", "text": "Command Line Options", "a_attr": {"href": "CommandLineOptions.html", "data-related": "[]"} },{ "id": "BD1DE09B14A14CB8881BB7B679458F44", "parent" : "#", "text": "context menu", "a_attr": {"href": "GUI.html", "data-related": "[{\"title\":\"GUI\",\"url\":\"GUI.html\"},{\"title\":\"Context Menu Items\",\"url\":\"ContextMenuItems.html\"}]"} },{ "id": "E21C632A3FAF4BC6BDAB4418731A1E9B", "parent" : "#", "text": "Converting .fcm", "a_attr": {"href": "Covertfcm.html", "data-related": "[]"} },{ "id": "A44056E52B9D4F1D92FF0381CEFB143D", "parent" : "#", "text": "crash", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "C3F18B6B73F040EBB0C50076EE4D43E5", "parent" : "#", "text": "Debugger", "a_attr": {"href": "Debugger.html", "data-related": "[]"} },{ "id": "33669B1FBF6A45419E04F0052831FFCC", "parent" : "#", "text": "desyncs", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "585DDCADF94F476E922E903A8B09F5B3", "parent" : "#", "text": "Directdraw", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "6F5AA0ADC7774F0FACEF8D77A7BA8BC7", "parent" : "#", "text": "Directory Overrides", "a_attr": {"href": "Directories.html", "data-related": "[]"} },{ "id": "841A91B28F9F41E897F467C77414C56C", "parent" : "#", "text": "Disable left+right/up+down", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "3B64C02E8DF444B18D4B5182B218041A", "parent" : "#", "text": "disksys.rom", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "68D573EA84A94D3CB2E5B9AF0EA92CCE", "parent" : "#", "text": "Eject/Insert Disk", "a_attr": {"href": "NES.html", "data-related": "[]"} },{ "id": "0305DBA147B744DF8563CE2AC078467D", "parent" : "#", "text": "Enable Background Input", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "97757DCD83594FF5B69EFE5E10DEFCD9", "parent" : "#", "text": "Enable Rewind", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "9CB3B9F922AD4F4DB9B0041C1EAE7668", "parent" : "#", "text": "Enable Run in Background", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "D624F1419D83468480589A273D9CDC8F", "parent" : "#", "text": "error", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "E1510892F05C458191C2DBFB3CD030BC", "parent" : "#", "text": "Famicom Controllers", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "64E177D0E41649229341B00E6400651B", "parent" : "#", "text": "Famicom Disk System", "a_attr": {"href": "FamicomDiskSytem.html", "data-related": "[]"} },{ "id": "43D54C0943AF459588A41B83D140AE90", "parent" : "#", "text": "FCEU-13-default_nitsuja.pal", "a_attr": {"href": "PaletteOptions.html", "data-related": "[]"} },{ "id": "6954B5855555483FB1B1B84EE8C61C8E", "parent" : "#", "text": "FCEU-15-nitsuja-new.pal", "a_attr": {"href": "PaletteOptions.html", "data-related": "[]"} },{ "id": "0E44F31BC17541A1AC1C2C641B87B469", "parent" : "#", "text": "FCEUX Movie File format", "a_attr": {"href": "fm2.html", "data-related": "[]"} },{ "id": "0BE022C96B86459BAB94E5970972E7E6", "parent" : "#", "text": "FCEUX.pal", "a_attr": {"href": "PaletteOptions.html", "data-related": "[]"} },{ "id": "5E3EBE0E1783430799CC79E0261A3170", "parent" : "#", "text": "FCM", "a_attr": {"href": "fcm.html", "data-related": "[]"} },{ "id": "52831D29488045389BA33786C0872BA7", "parent" : "#", "text": "fds", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "8946FAC9B0E44854AC09F438D4AAB8FF", "parent" : "#", "text": "FDS Bios", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "7E4DD855F8EF45FAB21E55EDB0F33F52", "parent" : "#", "text": "fm2", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "6B2683D79F294C9489A83BF57265CFDF", "parent" : "#", "text": "Full screen", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "90BC1FB40EA04694B5E77DBFA1031761", "parent" : "#", "text": "Game Genie", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "788AE7B752494EEC9D01AE6FC89F5F24", "parent" : "#", "text": "Game Genie Decoder/Encoder", "a_attr": {"href": "GameGenieEncoderDecoder.html", "data-related": "[]"} },{ "id": "7967C8614D984A4187724260700A4310", "parent" : "#", "text": "Game RAM Details", "a_attr": {"href": "NESRAMMappingFindingValues.html", "data-related": "[]"} },{ "id": "5DA2822D38F541E3AB5656914CED803D", "parent" : "#", "text": "Getting Started", "a_attr": {"href": "Gettingstarted.html", "data-related": "[]"} },{ "id": "DFC5605C06CF4FB8A18E2B7F9BDDA39E", "parent" : "#", "text": "GUI", "a_attr": {"href": "GUI.html", "data-related": "[]"} },{ "id": "0AC98DB694544F548021D8120ACEB596", "parent" : "#", "text": "Hacked Games", "a_attr": {"href": "Gamefilecompatibility.html", "data-related": "[]"} },{ "id": "BA8DA039CD4D4AEB84CBA7A7080496AD", "parent" : "#", "text": "Hex Editor", "a_attr": {"href": "HexEditor.html", "data-related": "[]"} },{ "id": "0B62849153C548AB8EDCF53B70BD9EEB", "parent" : "#", "text": "Hide Menu", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "81D227C0065B4C08BF3E420EEDF22410", "parent" : "#", "text": "History of FCEUX / FCE Ultra", "a_attr": {"href": "FCEUltraVersionHistory.html", "data-related": "[]"} },{ "id": "5B8EB280D1FA413D874484B4B1F95275", "parent" : "#", "text": "Inline Assembler", "a_attr": {"href": "Debugger.html", "data-related": "[]"} },{ "id": "F41A70678E2A4AA0B6709829BB93923B", "parent" : "#", "text": "Input Configuration", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "7DED0E0F330B4106B4917C777B3F2474", "parent" : "#", "text": "Input Presets", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "CC0F08EDCA64493DAF2E11B24792BE6E", "parent" : "#", "text": "Insert Coin", "a_attr": {"href": "NES.html", "data-related": "[]"} },{ "id": "6B02849550D74BAD9E8BDFA1B401192B", "parent" : "#", "text": "Loadstate", "a_attr": {"href": "Gettingstarted.html", "data-related": "[]"} },{ "id": "108624416B0247A68A0D070BFDB49A03", "parent" : "#", "text": "Lua", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "C82E31A5633E4DE9B09AF62FE3B6F7FD", "parent" : "#", "text": "Lua Functions", "a_attr": {"href": "LuaFunctionsList.html", "data-related": "[]"} },{ "id": "CC77E558CA7D405DBB7C358FEA586712", "parent" : "#", "text": "Lua Scripting", "a_attr": {"href": "#", "data-related": "[]"} },{ "id": "7FF4170AACB64CDF98AC5DEF8ACB237F", "parent" : "#", "text": "Making Game Genie codes", "a_attr": {"href": "GameGenieEncoderDecoder.html", "data-related": "[]"} },{ "id": "A7873179828C43F5B8279B8F9965F142", "parent" : "#", "text": "Map Hotkeys", "a_attr": {"href": "MapHotkeys.html", "data-related": "[]"} },{ "id": "0422396C49DB465A841D55C2FEF5CF40", "parent" : "#", "text": "Memory Map", "a_attr": {"href": "NESRAMMappingFindingValues.html", "data-related": "[]"} },{ "id": "573075F090E24E1AB86B9A84A89C7840", "parent" : "#", "text": "Memory Watch", "a_attr": {"href": "MemoryWatch.html", "data-related": "[]"} },{ "id": "3ACE3ABFF2AA40549169413FF50D8B62", "parent" : "#", "text": "Movie Recording", "a_attr": {"href": "MovieRecording.html", "data-related": "[]"} },{ "id": "E657AC5386D34EA1BB1A0A83F907BA16", "parent" : "#", "text": "Mute frame advance", "a_attr": {"href": "SoundOptions.html", "data-related": "[]"} },{ "id": "576FF21C6F9741C3911BAFFC887E806F", "parent" : "#", "text": "Name Table Viewer", "a_attr": {"href": "NameTableViewer.html", "data-related": "[]"} },{ "id": "411BB82AED86439FB9E39C006C785AAD", "parent" : "#", "text": "NES Mapping", "a_attr": {"href": "NESRAMMappingFindingValues.html", "data-related": "[]"} },{ "id": "1909B83FB9944546AB9D32BAA4DC65CC", "parent" : "#", "text": "Nestopia", "a_attr": {"href": "PaletteOptions.html", "data-related": "[]"} },{ "id": "1B43669183A449EC8652D9388142AD9D", "parent" : "#", "text": "Network Play", "a_attr": {"href": "NetworkPlay.html", "data-related": "[]"} },{ "id": "A452BC25766B45FABB122DEC195E2202", "parent" : "#", "text": "PAL Emulation", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "9519C5ECA1414E5A9FDC66E4B2856339", "parent" : "#", "text": "Palette", "a_attr": {"href": "Palette.html", "data-related": "[{\"title\":\"Palette\",\"url\":\"Palette.html\"},{\"title\":\"Palette Options\",\"url\":\"PaletteOptions.html\"},{\"title\":\"Troubleshooting\",\"url\":\"Troubleshooting.html\"}]"} },{ "id": "4AC4BAD72D8841D4B03B7D3545637538", "parent" : "#", "text": "Pause After Movie Playback", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "EA0820DB2B204DDB955F647F8A4BE64D", "parent" : "#", "text": "Power", "a_attr": {"href": "NES.html", "data-related": "[]"} },{ "id": "19BCC60C7C074FF2A0ED7755E173827B", "parent" : "#", "text": "Power Pad", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "948A816A25E642FF8EFD32F43105CBBF", "parent" : "#", "text": "PPU Viewer", "a_attr": {"href": "PPUViewer.html", "data-related": "[]"} },{ "id": "62BFC5C49AC54231A9F9F758EA010ACE", "parent" : "#", "text": "RAM Filter", "a_attr": {"href": "#", "data-related": "[]"} },{ "id": "994CD3263AEF46E9972882F598068725", "parent" : "#", "text": "Reset", "a_attr": {"href": "NES.html", "data-related": "[]"} },{ "id": "8022DE3BD91B439EAB655220B77FF7B0", "parent" : "#", "text": "right-click", "a_attr": {"href": "GUI.html", "data-related": "[]"} },{ "id": "99DE29C154D844F198742CFD81038DA9", "parent" : "#", "text": "ROM Hacking", "a_attr": {"href": "ROMHacking.html", "data-related": "[]"} },{ "id": "BA5DF8F9F6334FD3AFF388EE7809612C", "parent" : "#", "text": "Savestates", "a_attr": {"href": "Gettingstarted.html", "data-related": "[]"} },{ "id": "DB1F3F2A05084688AF82D792D428A72F", "parent" : "#", "text": "Setting up controllers", "a_attr": {"href": "Input.html", "data-related": "[]"} },{ "id": "C021EA3E1DCB457588DE543C90ECB22B", "parent" : "#", "text": "Show Movie Status Icon", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html", "data-related": "[]"} },{ "id": "C34E8DA010CA4720AD3BE6484716904E", "parent" : "#", "text": "slow emulation", "a_attr": {"href": "Video.html", "data-related": "[{\"title\":\"Video\",\"url\":\"Video.html\"},{\"title\":\"Troubleshooting\",\"url\":\"Troubleshooting.html\"}]"} },{ "id": "1CF1292970A94EA5A2F857CA5120D916", "parent" : "#", "text": "Sound Configuration", "a_attr": {"href": "SoundOptions.html", "data-related": "[]"} },{ "id": "5585E87D2CDC4441A215A196044A5F4D", "parent" : "#", "text": "Sound crackle", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "4DF9986C5D954E3BB5F7B32651F6BD94", "parent" : "#", "text": "Switch Disk Side", "a_attr": {"href": "NES.html", "data-related": "[]"} },{ "id": "7E683FAB32D647AF8DC8ACD5AE10700D", "parent" : "#", "text": "Symbolic Debugging", "a_attr": {"href": "Debugger.html", "data-related": "[]"} },{ "id": "A708BA7E95FF41369B6ACED3218281BD", "parent" : "#", "text": "TAS Edit", "a_attr": {"href": "TASEditor.html", "data-related": "[]"} },{ "id": "98FF63C3A60C4D86BA76F21FDF8BDAA8", "parent" : "#", "text": "Timings", "a_attr": {"href": "Timing.html", "data-related": "[]"} },{ "id": "720899A32F7B4CCE9DA2A7B9B59D33B2", "parent" : "#", "text": "Tool Assisted Speedruns", "a_attr": {"href": "ToolAssistedSpeedruns.html", "data-related": "[]"} },{ "id": "33057D7ACE3A41C7939F4484E0374AD2", "parent" : "#", "text": "Trace Logger", "a_attr": {"href": "TraceLogger.html", "data-related": "[]"} },{ "id": "5EDFD6686DA842A7A50E8906DC52B6E9", "parent" : "#", "text": "Troubleshooting", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "A7E64538FFE8462FB48DF722C8036E02", "parent" : "#", "text": "Undo", "a_attr": {"href": "Gettingstarted.html", "data-related": "[]"} },{ "id": "5B5B00294CEA4D209CE2B11E5895EBF9", "parent" : "#", "text": "Use External Input", "a_attr": {"href": ".html", "data-related": "[]"} },{ "id": "C36EFEDDA9CA4ED2BBFA9C1FE7CC8FDD", "parent" : "#", "text": "Valid Game Types", "a_attr": {"href": "Gamefilecompatibility.html", "data-related": "[]"} },{ "id": "F9A50A5EF1E2463287A1692EA437984F", "parent" : "#", "text": "Video Configuration", "a_attr": {"href": "Video.html", "data-related": "[]"} },{ "id": "182D155E0E2F430FAFB5ED77C93BA84C", "parent" : "#", "text": "Vista", "a_attr": {"href": "Troubleshooting.html", "data-related": "[]"} },{ "id": "62CE2C7A9814460FABE2A596F1A9B5BE", "parent" : "#", "text": "Volume", "a_attr": {"href": "SoundOptions.html", "data-related": "[]"} },{ "id": "86BF3587D83D4CBAB6DCC1ECBFD0EB8B", "parent" : "#", "text": "What's New?", "a_attr": {"href": "WhatsNew200.html", "data-related": "[]"} },{ "id": "03F514C91F7C4AC0BA0804E4002B0319", "parent" : "#", "text": "Zapper", "a_attr": {"href": "Input.html", "data-related": "[]"} }] \ No newline at end of file diff --git a/web/help/_toc.json b/web/help/_toc.json new file mode 100644 index 00000000..f15bca97 --- /dev/null +++ b/web/help/_toc.json @@ -0,0 +1 @@ +[{ "id": "Intro", "parent" : "#", "text": "Introduction", "a_attr": {"href": "Intro.html"} },{ "id": "Introduction", "parent" : "Intro", "text": "Introduction", "a_attr": {"href": "Introduction.html"} },{ "id": "Overview", "parent" : "Intro", "text": "Overview", "a_attr": {"href": "Overview.html"} },{ "id": "FCEUltraVersionHistory", "parent" : "Intro", "text": "FCE Ultra Version History", "a_attr": {"href": "FCEUltraVersionHistory.html"} },{ "id": "Newtopic", "parent" : "Intro", "text": "What's New? 2.3.0 (changelog)", "a_attr": {"href": "Newtopic.html"} },{ "id": "WhatsNew223", "parent" : "Intro", "text": "What's New? 2.2.3 (changelog)", "a_attr": {"href": "WhatsNew223.html"} },{ "id": "WhatsNew222", "parent" : "Intro", "text": "What's New? 2.2.2 (changelog)", "a_attr": {"href": "WhatsNew222.html"} },{ "id": "WhatsNew221", "parent" : "Intro", "text": "What's New? 2.2.1 (changelog)", "a_attr": {"href": "WhatsNew221.html"} },{ "id": "WhatsNew220", "parent" : "Intro", "text": "What's New? 2.2.0 (changelog)", "a_attr": {"href": "WhatsNew220.html"} },{ "id": "WhatsNew215", "parent" : "Intro", "text": "What's New? 2.1.5 (changelog)", "a_attr": {"href": "WhatsNew215.html"} },{ "id": "WhatsNew214", "parent" : "Intro", "text": "What's New? 2.1.4 (changelog)", "a_attr": {"href": "WhatsNew214.html"} },{ "id": "WhatsNew213", "parent" : "Intro", "text": "What's New? 2.1.3 (changelog)", "a_attr": {"href": "WhatsNew213.html"} },{ "id": "WhatsNew212", "parent" : "Intro", "text": "What's New? 2.1.2 (changelog)", "a_attr": {"href": "WhatsNew212.html"} },{ "id": "WhatsNew211", "parent" : "Intro", "text": "What's New? 2.1.1 (changelog)", "a_attr": {"href": "WhatsNew211.html"} },{ "id": "WhatsNew210", "parent" : "Intro", "text": "What's New? 2.1 (changelog)", "a_attr": {"href": "WhatsNew210.html"} },{ "id": "WhatsNew203", "parent" : "Intro", "text": "What's New? 2.0.3 (changelog)", "a_attr": {"href": "WhatsNew203.html"} },{ "id": "WhatsNew202", "parent" : "Intro", "text": "What's New? 2.0.2 (changelog)", "a_attr": {"href": "WhatsNew202.html"} },{ "id": "WhatsNew201", "parent" : "Intro", "text": "What's New? 2.0.1 (changelog)", "a_attr": {"href": "WhatsNew201.html"} },{ "id": "WhatsNew200", "parent" : "Intro", "text": "What's New? 2.0.0", "a_attr": {"href": "WhatsNew200.html"} },{ "id": "General", "parent" : "#", "text": "General", "a_attr": {"href": "General.html"} },{ "id": "Gettingstarted", "parent" : "General", "text": "Getting Started", "a_attr": {"href": "Gettingstarted.html"} },{ "id": "Gamefilecompatibility", "parent" : "General", "text": "Game file compatibility", "a_attr": {"href": "Gamefilecompatibility.html"} },{ "id": "CommandLineOptions", "parent" : "General", "text": "Command Line Options", "a_attr": {"href": "CommandLineOptions.html"} },{ "id": "CustomizingthroughtheConfigFil", "parent" : "General", "text": "Customizing through the Config File", "a_attr": {"href": "CustomizingthroughtheConfigFil.html"} },{ "id": "FamicomDiskSytem", "parent" : "General", "text": "Famicom Disk Sytem", "a_attr": {"href": "FamicomDiskSytem.html"} },{ "id": "AVICapturing", "parent" : "FamicomDiskSytem", "text": "AVI Capturing", "a_attr": {"href": "AVICapturing.html"} },{ "id": "MovieRecording", "parent" : "General", "text": "Movie Recording", "a_attr": {"href": "MovieRecording.html"} },{ "id": "NES", "parent" : "General", "text": "NES Menu", "a_attr": {"href": "NES.html"} },{ "id": "PaletteOptions", "parent" : "General", "text": "Palette Options", "a_attr": {"href": "PaletteOptions.html"} },{ "id": "Config", "parent" : "#", "text": "Config", "a_attr": {"href": "Config.html"} },{ "id": "ToggleSwitchesHideMenuetc", "parent" : "Config", "text": "Menu Items & Submenus", "a_attr": {"href": "ToggleSwitchesHideMenuetc.html"} },{ "id": "Directories", "parent" : "Config", "text": "Directories", "a_attr": {"href": "Directories.html"} },{ "id": "GUI", "parent" : "Config", "text": "GUI", "a_attr": {"href": "GUI.html"} },{ "id": "Input", "parent" : "Config", "text": "Input", "a_attr": {"href": "Input.html"} },{ "id": "NetworkPlay", "parent" : "Config", "text": "Network Play", "a_attr": {"href": "NetworkPlay.html"} },{ "id": "Palette", "parent" : "Config", "text": "Palette", "a_attr": {"href": "Palette.html"} },{ "id": "SoundOptions", "parent" : "Config", "text": "Sound", "a_attr": {"href": "SoundOptions.html"} },{ "id": "Timing", "parent" : "Config", "text": "Timing", "a_attr": {"href": "Timing.html"} },{ "id": "Video", "parent" : "Config", "text": "Video", "a_attr": {"href": "Video.html"} },{ "id": "MovieOptions", "parent" : "Config", "text": "Movie Options", "a_attr": {"href": "MovieOptions.html"} },{ "id": "MapHotkeys", "parent" : "Config", "text": "Map Hotkeys", "a_attr": {"href": "MapHotkeys.html"} },{ "id": "ContextMenuItems", "parent" : "Config", "text": "Context Menu Items", "a_attr": {"href": "ContextMenuItems.html"} },{ "id": "Tools2", "parent" : "#", "text": "Tools", "a_attr": {"href": "Tools2.html"} },{ "id": "CheatSearch", "parent" : "Tools2", "text": "Cheat Search", "a_attr": {"href": "CheatSearch.html"} },{ "id": "RAMSearch", "parent" : "Tools2", "text": "RAM Search", "a_attr": {"href": "RAMSearch.html"} },{ "id": "RAMWatch", "parent" : "Tools2", "text": "RAM Watch", "a_attr": {"href": "RAMWatch.html"} },{ "id": "MemoryWatch", "parent" : "Tools2", "text": "Memory Watch", "a_attr": {"href": "MemoryWatch.html"} },{ "id": "TASEditor", "parent" : "Tools2", "text": "TAS Editor", "a_attr": {"href": "TASEditor.html"} },{ "id": "Covertfcm", "parent" : "Tools2", "text": "Convert fcm", "a_attr": {"href": "Covertfcm.html"} },{ "id": "AutoFireConfigurations", "parent" : "Tools2", "text": "Auto Fire Settings", "a_attr": {"href": "AutoFireConfigurations.html"} },{ "id": "TextHooker", "parent" : "Tools2", "text": "Text Hooker", "a_attr": {"href": "TextHooker.html"} },{ "id": "Debug", "parent" : "#", "text": "Debug", "a_attr": {"href": "Debug.html"} },{ "id": "Debugger", "parent" : "Debug", "text": "Debugger", "a_attr": {"href": "Debugger.html"} },{ "id": "PPUViewer", "parent" : "Debug", "text": "PPU Viewer", "a_attr": {"href": "PPUViewer.html"} },{ "id": "NameTableViewer", "parent" : "Debug", "text": "Name Table Viewer", "a_attr": {"href": "NameTableViewer.html"} },{ "id": "HexEditor", "parent" : "Debug", "text": "Hex Editor", "a_attr": {"href": "HexEditor.html"} },{ "id": "TraceLogger", "parent" : "Debug", "text": "Trace Logger", "a_attr": {"href": "TraceLogger.html"} },{ "id": "CodeDataLogger", "parent" : "Debug", "text": "Code/Data Logger", "a_attr": {"href": "CodeDataLogger.html"} },{ "id": "GameGenieEncoderDecoder", "parent" : "Debug", "text": "Game Genie Encoder/Decoder", "a_attr": {"href": "GameGenieEncoderDecoder.html"} },{ "id": "LuaScripting", "parent" : "#", "text": "Lua Scripting", "a_attr": {"href": "LuaScripting.html"} },{ "id": "LuaGettingStarted", "parent" : "LuaScripting", "text": "Getting Started", "a_attr": {"href": "LuaGettingStarted.html"} },{ "id": "Commands", "parent" : "LuaScripting", "text": "Using Lua", "a_attr": {"href": "Commands.html"} },{ "id": "LuaFunctionsList", "parent" : "LuaScripting", "text": "Lua Functions List", "a_attr": {"href": "LuaFunctionsList.html"} },{ "id": "LuaPerks", "parent" : "LuaScripting", "text": "LuaPerks", "a_attr": {"href": "LuaPerks.html"} },{ "id": "LuaBot", "parent" : "LuaScripting", "text": "Lua Bot", "a_attr": {"href": "LuaBot.html"} },{ "id": "OverviewofIncludedScripts", "parent" : "LuaScripting", "text": "Overview of Included Scripts", "a_attr": {"href": "OverviewofIncludedScripts.html"} },{ "id": "FAQGuides", "parent" : "#", "text": "FAQ / Guides", "a_attr": {"href": "FAQGuides.html"} },{ "id": "Troubleshooting", "parent" : "FAQGuides", "text": "Troubleshooting", "a_attr": {"href": "Troubleshooting.html"} },{ "id": "ToolAssistedSpeedruns", "parent" : "FAQGuides", "text": "Tool Assisted Speedruns", "a_attr": {"href": "ToolAssistedSpeedruns.html"} },{ "id": "ROMHacking", "parent" : "FAQGuides", "text": "ROM Hacking", "a_attr": {"href": "ROMHacking.html"} },{ "id": "NESRAMMappingFindingValues", "parent" : "FAQGuides", "text": "NES RAM (Mapping/Finding Values)", "a_attr": {"href": "NESRAMMappingFindingValues.html"} },{ "id": "Technicalinformation", "parent" : "#", "text": "Technical Information", "a_attr": {"href": "Technicalinformation.html"} },{ "id": "Movieformats", "parent" : "Technicalinformation", "text": "Movie & Savestate formats", "a_attr": {"href": "Movieformats.html"} },{ "id": "fm2", "parent" : "Movieformats", "text": ".fm2", "a_attr": {"href": "fm2.html"} },{ "id": "fcm", "parent" : "Movieformats", "text": ".fcm", "a_attr": {"href": "fcm.html"} },{ "id": "fcs", "parent" : "Movieformats", "text": "Savestate (.fcs)", "a_attr": {"href": "fcs.html"} },{ "id": "Sound", "parent" : "Technicalinformation", "text": "Sound", "a_attr": {"href": "Sound.html"} },{ "id": "NSFFormat", "parent" : "Sound", "text": "NSF Format", "a_attr": {"href": "NSFFormat.html"} },{ "id": "NESSound", "parent" : "Sound", "text": "NES Sound", "a_attr": {"href": "NESSound.html"} },{ "id": "NESProcessor", "parent" : "Technicalinformation", "text": "NES Processing", "a_attr": {"href": "NESProcessor.html"} },{ "id": "6502CPU", "parent" : "NESProcessor", "text": "CPU - 6502", "a_attr": {"href": "6502CPU.html"} },{ "id": "PPU", "parent" : "NESProcessor", "text": "PPU - 2C02", "a_attr": {"href": "PPU.html"} },{ "id": "NESScrolling1", "parent" : "NESProcessor", "text": "NES Scrolling 1", "a_attr": {"href": "NESScrolling1.html"} },{ "id": "NESScrolling2", "parent" : "NESProcessor", "text": "NES Scrolling 2", "a_attr": {"href": "NESScrolling2.html"} },{ "id": "NLFilesFormat", "parent" : "Technicalinformation", "text": ".nl files format", "a_attr": {"href": "NLFilesFormat.html"} }] \ No newline at end of file diff --git a/web/help/_translations.js b/web/help/_translations.js new file mode 100644 index 00000000..36b7fded --- /dev/null +++ b/web/help/_translations.js @@ -0,0 +1,11 @@ + +function hnd_ut(a){ +a.TRANSLATIONS['Search term too short'] = "Search term too short"; +a.TRANSLATIONS['No results'] = "No results"; +a.TRANSLATIONS['Please enter 3 or more characters'] = "Please enter 3 or more characters"; +a.TRANSLATIONS['Word list not ready yet. Please wait until the word list is fully downloaded'] = "Word list not ready yet. Please wait until the word list is fully downloaded"; +a.TRANSLATIONS['Incorrect or corrupt search data. Please check your HelpNDoc template'] = "Incorrect or corrupt search data. Please check your HelpNDoc template"; +a.TRANSLATIONS['Related topics...'] = "Related topics..."; +a.TRANSLATIONS['Loading...'] = "Loading..."; +a.TRANSLATIONS['Close'] = "Close"; +} diff --git a/web/help/context/0.html b/web/help/context/0.html new file mode 100644 index 00000000..1cf3994a --- /dev/null +++ b/web/help/context/0.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Introduction" + + + + + + + + diff --git a/web/help/context/1.html b/web/help/context/1.html new file mode 100644 index 00000000..106e1e13 --- /dev/null +++ b/web/help/context/1.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "General" + + + + + + + + diff --git a/web/help/context/10.html b/web/help/context/10.html new file mode 100644 index 00000000..48e1a3f3 --- /dev/null +++ b/web/help/context/10.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Memory Watch" + + + + + + + + diff --git a/web/help/context/11.html b/web/help/context/11.html new file mode 100644 index 00000000..0bd437cd --- /dev/null +++ b/web/help/context/11.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua Scripting" + + + + + + + + diff --git a/web/help/context/12.html b/web/help/context/12.html new file mode 100644 index 00000000..126d706e --- /dev/null +++ b/web/help/context/12.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Getting Started" + + + + + + + + diff --git a/web/help/context/13.html b/web/help/context/13.html new file mode 100644 index 00000000..52c23404 --- /dev/null +++ b/web/help/context/13.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Auto Fire Settings" + + + + + + + + diff --git a/web/help/context/14.html b/web/help/context/14.html new file mode 100644 index 00000000..3df806a1 --- /dev/null +++ b/web/help/context/14.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Debugger" + + + + + + + + diff --git a/web/help/context/15.html b/web/help/context/15.html new file mode 100644 index 00000000..0229fade --- /dev/null +++ b/web/help/context/15.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Hex Editor" + + + + + + + + diff --git a/web/help/context/16.html b/web/help/context/16.html new file mode 100644 index 00000000..559c93d2 --- /dev/null +++ b/web/help/context/16.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "PPU Viewer" + + + + + + + + diff --git a/web/help/context/17.html b/web/help/context/17.html new file mode 100644 index 00000000..4cd92b40 --- /dev/null +++ b/web/help/context/17.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Name Table Viewer" + + + + + + + + diff --git a/web/help/context/18.html b/web/help/context/18.html new file mode 100644 index 00000000..1d9d12ec --- /dev/null +++ b/web/help/context/18.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "RAM Search" + + + + + + + + diff --git a/web/help/context/19.html b/web/help/context/19.html new file mode 100644 index 00000000..3aba801b --- /dev/null +++ b/web/help/context/19.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "FAQ / Guides" + + + + + + + + diff --git a/web/help/context/2.html b/web/help/context/2.html new file mode 100644 index 00000000..0476dba3 --- /dev/null +++ b/web/help/context/2.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Overview" + + + + + + + + diff --git a/web/help/context/20.html b/web/help/context/20.html new file mode 100644 index 00000000..8e6527bf --- /dev/null +++ b/web/help/context/20.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Tool Assisted Speedruns" + + + + + + + + diff --git a/web/help/context/21.html b/web/help/context/21.html new file mode 100644 index 00000000..80f9f390 --- /dev/null +++ b/web/help/context/21.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "ROM Hacking" + + + + + + + + diff --git a/web/help/context/22.html b/web/help/context/22.html new file mode 100644 index 00000000..23dc33d8 --- /dev/null +++ b/web/help/context/22.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.0" + + + + + + + + diff --git a/web/help/context/23.html b/web/help/context/23.html new file mode 100644 index 00000000..049fe6db --- /dev/null +++ b/web/help/context/23.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Technical Information" + + + + + + + + diff --git a/web/help/context/24.html b/web/help/context/24.html new file mode 100644 index 00000000..57968b5e --- /dev/null +++ b/web/help/context/24.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Movie & Savestate formats" + + + + + + + + diff --git a/web/help/context/25.html b/web/help/context/25.html new file mode 100644 index 00000000..3bc32fb8 --- /dev/null +++ b/web/help/context/25.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to ".fm2" + + + + + + + + diff --git a/web/help/context/26.html b/web/help/context/26.html new file mode 100644 index 00000000..1264910e --- /dev/null +++ b/web/help/context/26.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to ".fcm" + + + + + + + + diff --git a/web/help/context/27.html b/web/help/context/27.html new file mode 100644 index 00000000..133b973d --- /dev/null +++ b/web/help/context/27.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Savestate (.fcs)" + + + + + + + + diff --git a/web/help/context/28.html b/web/help/context/28.html new file mode 100644 index 00000000..a1b91d7c --- /dev/null +++ b/web/help/context/28.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Sound" + + + + + + + + diff --git a/web/help/context/29.html b/web/help/context/29.html new file mode 100644 index 00000000..d75682b8 --- /dev/null +++ b/web/help/context/29.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NSF Format" + + + + + + + + diff --git a/web/help/context/3.html b/web/help/context/3.html new file mode 100644 index 00000000..b3a39aa0 --- /dev/null +++ b/web/help/context/3.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "FCE Ultra Version History" + + + + + + + + diff --git a/web/help/context/30.html b/web/help/context/30.html new file mode 100644 index 00000000..df9766cf --- /dev/null +++ b/web/help/context/30.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Sound" + + + + + + + + diff --git a/web/help/context/31.html b/web/help/context/31.html new file mode 100644 index 00000000..645f7457 --- /dev/null +++ b/web/help/context/31.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Processing" + + + + + + + + diff --git a/web/help/context/32.html b/web/help/context/32.html new file mode 100644 index 00000000..1a1d74d8 --- /dev/null +++ b/web/help/context/32.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "CPU - 6502" + + + + + + + + diff --git a/web/help/context/33.html b/web/help/context/33.html new file mode 100644 index 00000000..ae6ca58a --- /dev/null +++ b/web/help/context/33.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "PPU - 2C02" + + + + + + + + diff --git a/web/help/context/34.html b/web/help/context/34.html new file mode 100644 index 00000000..b434083a --- /dev/null +++ b/web/help/context/34.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Scrolling 1" + + + + + + + + diff --git a/web/help/context/35.html b/web/help/context/35.html new file mode 100644 index 00000000..69f17194 --- /dev/null +++ b/web/help/context/35.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Scrolling 2" + + + + + + + + diff --git a/web/help/context/36.html b/web/help/context/36.html new file mode 100644 index 00000000..f1a7ce19 --- /dev/null +++ b/web/help/context/36.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES RAM (Mapping/Finding Values)" + + + + + + + + diff --git a/web/help/context/37.html b/web/help/context/37.html new file mode 100644 index 00000000..6e52beb0 --- /dev/null +++ b/web/help/context/37.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Debug" + + + + + + + + diff --git a/web/help/context/38.html b/web/help/context/38.html new file mode 100644 index 00000000..7cfe9b76 --- /dev/null +++ b/web/help/context/38.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Trace Logger" + + + + + + + + diff --git a/web/help/context/39.html b/web/help/context/39.html new file mode 100644 index 00000000..67833dbb --- /dev/null +++ b/web/help/context/39.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Code/Data Logger" + + + + + + + + diff --git a/web/help/context/4.html b/web/help/context/4.html new file mode 100644 index 00000000..35fbfde2 --- /dev/null +++ b/web/help/context/4.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Getting Started" + + + + + + + + diff --git a/web/help/context/40.html b/web/help/context/40.html new file mode 100644 index 00000000..5667ae51 --- /dev/null +++ b/web/help/context/40.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Game Genie Encoder/Decoder" + + + + + + + + diff --git a/web/help/context/41.html b/web/help/context/41.html new file mode 100644 index 00000000..44face0b --- /dev/null +++ b/web/help/context/41.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Config" + + + + + + + + diff --git a/web/help/context/42.html b/web/help/context/42.html new file mode 100644 index 00000000..21df67a0 --- /dev/null +++ b/web/help/context/42.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Input" + + + + + + + + diff --git a/web/help/context/43.html b/web/help/context/43.html new file mode 100644 index 00000000..dec41dfa --- /dev/null +++ b/web/help/context/43.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Directories" + + + + + + + + diff --git a/web/help/context/44.html b/web/help/context/44.html new file mode 100644 index 00000000..6df1f15c --- /dev/null +++ b/web/help/context/44.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Sound" + + + + + + + + diff --git a/web/help/context/45.html b/web/help/context/45.html new file mode 100644 index 00000000..7cc12aa3 --- /dev/null +++ b/web/help/context/45.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Video" + + + + + + + + diff --git a/web/help/context/46.html b/web/help/context/46.html new file mode 100644 index 00000000..baac4b3b --- /dev/null +++ b/web/help/context/46.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Map Hotkeys" + + + + + + + + diff --git a/web/help/context/47.html b/web/help/context/47.html new file mode 100644 index 00000000..ebd4ad7e --- /dev/null +++ b/web/help/context/47.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.3 (changelog)" + + + + + + + + diff --git a/web/help/context/48.html b/web/help/context/48.html new file mode 100644 index 00000000..36c99d3f --- /dev/null +++ b/web/help/context/48.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.1 (changelog)" + + + + + + + + diff --git a/web/help/context/49.html b/web/help/context/49.html new file mode 100644 index 00000000..af67d469 --- /dev/null +++ b/web/help/context/49.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "TAS Editor" + + + + + + + + diff --git a/web/help/context/5.html b/web/help/context/5.html new file mode 100644 index 00000000..652c6cda --- /dev/null +++ b/web/help/context/5.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Movie Recording" + + + + + + + + diff --git a/web/help/context/50.html b/web/help/context/50.html new file mode 100644 index 00000000..29ea43ab --- /dev/null +++ b/web/help/context/50.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Command Line Options" + + + + + + + + diff --git a/web/help/context/51.html b/web/help/context/51.html new file mode 100644 index 00000000..c89abb09 --- /dev/null +++ b/web/help/context/51.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Menu Items & Submenus" + + + + + + + + diff --git a/web/help/context/52.html b/web/help/context/52.html new file mode 100644 index 00000000..a96e0d9b --- /dev/null +++ b/web/help/context/52.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Timing" + + + + + + + + diff --git a/web/help/context/53.html b/web/help/context/53.html new file mode 100644 index 00000000..39881f50 --- /dev/null +++ b/web/help/context/53.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "GUI" + + + + + + + + diff --git a/web/help/context/54.html b/web/help/context/54.html new file mode 100644 index 00000000..2239f70f --- /dev/null +++ b/web/help/context/54.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Palette" + + + + + + + + diff --git a/web/help/context/55.html b/web/help/context/55.html new file mode 100644 index 00000000..48f78207 --- /dev/null +++ b/web/help/context/55.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Network Play" + + + + + + + + diff --git a/web/help/context/56.html b/web/help/context/56.html new file mode 100644 index 00000000..5beef1a4 --- /dev/null +++ b/web/help/context/56.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Menu" + + + + + + + + diff --git a/web/help/context/57.html b/web/help/context/57.html new file mode 100644 index 00000000..afb031e7 --- /dev/null +++ b/web/help/context/57.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Game file compatibility" + + + + + + + + diff --git a/web/help/context/58.html b/web/help/context/58.html new file mode 100644 index 00000000..879f638c --- /dev/null +++ b/web/help/context/58.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Convert fcm" + + + + + + + + diff --git a/web/help/context/59.html b/web/help/context/59.html new file mode 100644 index 00000000..8a766088 --- /dev/null +++ b/web/help/context/59.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Introduction" + + + + + + + + diff --git a/web/help/context/6.html b/web/help/context/6.html new file mode 100644 index 00000000..5042dfdb --- /dev/null +++ b/web/help/context/6.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "AVI Capturing" + + + + + + + + diff --git a/web/help/context/60.html b/web/help/context/60.html new file mode 100644 index 00000000..70c9acde --- /dev/null +++ b/web/help/context/60.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Text Hooker" + + + + + + + + diff --git a/web/help/context/61.html b/web/help/context/61.html new file mode 100644 index 00000000..7c719d72 --- /dev/null +++ b/web/help/context/61.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Using Lua" + + + + + + + + diff --git a/web/help/context/62.html b/web/help/context/62.html new file mode 100644 index 00000000..86675349 --- /dev/null +++ b/web/help/context/62.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.2 (changelog)" + + + + + + + + diff --git a/web/help/context/63.html b/web/help/context/63.html new file mode 100644 index 00000000..4dd937d8 --- /dev/null +++ b/web/help/context/63.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua Bot" + + + + + + + + diff --git a/web/help/context/64.html b/web/help/context/64.html new file mode 100644 index 00000000..714adbc9 --- /dev/null +++ b/web/help/context/64.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua Functions List" + + + + + + + + diff --git a/web/help/context/65.html b/web/help/context/65.html new file mode 100644 index 00000000..0a79096f --- /dev/null +++ b/web/help/context/65.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.3 (changelog)" + + + + + + + + diff --git a/web/help/context/66.html b/web/help/context/66.html new file mode 100644 index 00000000..e599d0f3 --- /dev/null +++ b/web/help/context/66.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Movie Options" + + + + + + + + diff --git a/web/help/context/67.html b/web/help/context/67.html new file mode 100644 index 00000000..6bf94af1 --- /dev/null +++ b/web/help/context/67.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1 (changelog)" + + + + + + + + diff --git a/web/help/context/68.html b/web/help/context/68.html new file mode 100644 index 00000000..45636678 --- /dev/null +++ b/web/help/context/68.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Context Menu Items" + + + + + + + + diff --git a/web/help/context/69.html b/web/help/context/69.html new file mode 100644 index 00000000..98f80186 --- /dev/null +++ b/web/help/context/69.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Palette Options" + + + + + + + + diff --git a/web/help/context/7.html b/web/help/context/7.html new file mode 100644 index 00000000..da983b3c --- /dev/null +++ b/web/help/context/7.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Famicom Disk Sytem" + + + + + + + + diff --git a/web/help/context/70.html b/web/help/context/70.html new file mode 100644 index 00000000..41659069 --- /dev/null +++ b/web/help/context/70.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Troubleshooting" + + + + + + + + diff --git a/web/help/context/71.html b/web/help/context/71.html new file mode 100644 index 00000000..2d181ff1 --- /dev/null +++ b/web/help/context/71.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Customizing through the Config File" + + + + + + + + diff --git a/web/help/context/72.html b/web/help/context/72.html new file mode 100644 index 00000000..dc09d615 --- /dev/null +++ b/web/help/context/72.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.1 (changelog)" + + + + + + + + diff --git a/web/help/context/73.html b/web/help/context/73.html new file mode 100644 index 00000000..ed12bbee --- /dev/null +++ b/web/help/context/73.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.2 (changelog)" + + + + + + + + diff --git a/web/help/context/74.html b/web/help/context/74.html new file mode 100644 index 00000000..1fc11711 --- /dev/null +++ b/web/help/context/74.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "RAM Watch" + + + + + + + + diff --git a/web/help/context/75.html b/web/help/context/75.html new file mode 100644 index 00000000..e38276c3 --- /dev/null +++ b/web/help/context/75.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.3 (changelog)" + + + + + + + + diff --git a/web/help/context/76.html b/web/help/context/76.html new file mode 100644 index 00000000..b7237cca --- /dev/null +++ b/web/help/context/76.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.1 (changelog)" + + + + + + + + diff --git a/web/help/context/77.html b/web/help/context/77.html new file mode 100644 index 00000000..e0613194 --- /dev/null +++ b/web/help/context/77.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.4 (changelog)" + + + + + + + + diff --git a/web/help/context/78.html b/web/help/context/78.html new file mode 100644 index 00000000..674eb65e --- /dev/null +++ b/web/help/context/78.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.5 (changelog)" + + + + + + + + diff --git a/web/help/context/79.html b/web/help/context/79.html new file mode 100644 index 00000000..165278d5 --- /dev/null +++ b/web/help/context/79.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Overview of Included Scripts" + + + + + + + + diff --git a/web/help/context/8.html b/web/help/context/8.html new file mode 100644 index 00000000..e21a82f0 --- /dev/null +++ b/web/help/context/8.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Tools" + + + + + + + + diff --git a/web/help/context/80.html b/web/help/context/80.html new file mode 100644 index 00000000..0d7a8674 --- /dev/null +++ b/web/help/context/80.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.0 (changelog)" + + + + + + + + diff --git a/web/help/context/81.html b/web/help/context/81.html new file mode 100644 index 00000000..0905e6e5 --- /dev/null +++ b/web/help/context/81.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "LuaPerks" + + + + + + + + diff --git a/web/help/context/82.html b/web/help/context/82.html new file mode 100644 index 00000000..4d67f7ba --- /dev/null +++ b/web/help/context/82.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.2 (changelog)" + + + + + + + + diff --git a/web/help/context/83.html b/web/help/context/83.html new file mode 100644 index 00000000..7bf5b51c --- /dev/null +++ b/web/help/context/83.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to ".nl files format" + + + + + + + + diff --git a/web/help/context/84.html b/web/help/context/84.html new file mode 100644 index 00000000..dcf75712 --- /dev/null +++ b/web/help/context/84.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.3.0 (changelog)" + + + + + + + + diff --git a/web/help/context/9.html b/web/help/context/9.html new file mode 100644 index 00000000..bec6086c --- /dev/null +++ b/web/help/context/9.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Cheat Search" + + + + + + + + diff --git a/web/help/css/effects.min.css b/web/help/css/effects.min.css new file mode 100644 index 00000000..37f33b1a --- /dev/null +++ b/web/help/css/effects.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */header{transition:top 0.3s ease, padding-left 0.3s ease}div#main{transition:margin-left 0.3s ease}nav{transition:left 0.3s ease, margin-top 0.3s ease, opacity 0.3s ease}.mask{transition:visibility 0s, opacity 0.3s ease}.tab-tabs>li::after{transition:transform 250ms ease 0s}#hnd-splitter{transition:background-color 0.15s linear} diff --git a/web/help/css/hnd.content.css b/web/help/css/hnd.content.css new file mode 100644 index 00000000..1f3c88b0 --- /dev/null +++ b/web/help/css/hnd.content.css @@ -0,0 +1,755 @@ +/* ========== Text Styles ========== */ +hr { color: #000000} +.main-content, .main-content table span.rvts0 /* Normal text */ +{ + font-size: 10pt; + font-family: 'Arial', 'Helvetica', sans-serif; + font-style: normal; + font-weight: normal; + color: #000000; + text-decoration: none; +} +span.rvts1 /* Heading */ +{ + font-weight: bold; + color: #0000ff; +} +span.rvts2 /* Subheading */ +{ + font-weight: bold; + color: #000080; +} +span.rvts3 /* Keywords */ +{ + font-style: italic; + color: #800000; +} +a.rvts4, span.rvts4 /* Jump 1 */ +{ + color: #008000; + text-decoration: underline; +} +a.rvts5, span.rvts5 /* Jump 2 */ +{ + color: #008000; + text-decoration: underline; +} +span.rvts6 +{ +} +span.rvts7 +{ + font-weight: bold; + color: #0000ff; +} +span.rvts8 +{ + font-weight: bold; + color: #000080; +} +span.rvts9 +{ + font-style: italic; + color: #800000; +} +a.rvts10, span.rvts10 +{ + color: #008000; + text-decoration: underline; +} +span.rvts11 +{ + color: #a0a0a0; +} +span.rvts12 +{ + font-size: 15pt; + font-family: 'Tahoma', 'Geneva', sans-serif; + font-weight: bold; + color: #696969; +} +span.rvts13 +{ + font-weight: bold; + color: #a0a0a0; +} +span.rvts14 +{ + font-style: italic; + color: #a0a0a0; +} +span.rvts15 +{ + font-size: 12pt; +} +a.rvts16, span.rvts16 +{ + font-size: 12pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts16:hover +{ + color: #0000ff; +} +span.rvts17 +{ + font-size: 18pt; +} +span.rvts18 /* Font Style */ +{ + font-family: 'Tahoma', 'Geneva', sans-serif; + font-style: italic; + color: #c0c0c0; +} +a.rvts19, span.rvts19 /* Font Style */ +{ + font-family: 'Tahoma', 'Geneva', sans-serif; + font-style: italic; + color: #6666ff; + text-decoration: underline; +} +span.rvts20 +{ + text-decoration: underline; +} +span.rvts21 +{ + font-size: 14pt; +} +span.rvts22 +{ + font-size: 24pt; + text-decoration: underline; +} +a.rvts23, span.rvts23 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts23:hover +{ + color: #0000ff; +} +a.rvts24, span.rvts24 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts24:hover +{ + color: #0000ff; +} +span.rvts25 +{ + font-size: 12pt; + text-decoration: underline; +} +span.rvts26 +{ + font-size: 18pt; + text-decoration: underline; +} +span.rvts27 +{ + color: #000000; +} +span.rvts28 +{ + font-size: 16pt; + color: #000000; +} +span.rvts29 +{ + font-size: 14pt; + color: #000000; +} +span.rvts30 +{ + font-size: 12pt; + color: #000000; +} +span.rvts31 +{ + font-size: 12pt; + font-family: 'Times New Roman', 'Times', serif; + color: #000000; +} +span.rvts32 +{ +} +span.rvts33 +{ + font-size: 14pt; +} +span.rvts34 +{ + font-size: 16pt; +} +a.rvts35, span.rvts35 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts35:hover +{ + color: #0000ff; +} +a.rvts36, span.rvts36 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts36:hover +{ + color: #0000ff; +} +span.rvts37 +{ + font-size: 16pt; +} +a.rvts38, span.rvts38 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts38:hover +{ + color: #0000ff; +} +span.rvts39 +{ + font-family: 'Lucida Console', 'Monaco', monospace; +} +span.rvts40 +{ + font-style: italic; +} +a.rvts41, span.rvts41 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts41:hover +{ + color: #0000ff; +} +span.rvts42 +{ + font-family: 'Times New Roman', 'Times', serif; +} +span.rvts43 +{ + font-size: 11pt; + font-family: 'Courier New', 'Courier', monospace; +} +a.rvts44, span.rvts44 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts44:hover +{ + color: #0000ff; +} +span.rvts45 +{ + font-weight: bold; +} +a.rvts46, span.rvts46 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts46:hover +{ + color: #0000ff; +} +a.rvts47, span.rvts47 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts47:hover +{ + color: #0000ff; +} +span.rvts48 +{ + font-size: 16pt; + text-decoration: underline; +} +a.rvts49, span.rvts49 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts49:hover +{ + color: #0000ff; +} +span.rvts50 +{ + font-size: 24pt; +} +a.rvts51, span.rvts51 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts51:hover +{ + color: #0000ff; +} +span.rvts52 +{ + font-size: 14pt; + text-decoration: underline; +} +span.rvts53 +{ + font-family: 'Courier New', 'Courier', monospace; +} +span.rvts54 +{ + font-size: 9pt; +} +a.rvts55, span.rvts55 +{ + font-size: 9pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts55:hover +{ + color: #0000ff; +} +span.rvts56 +{ + font-family: 'Courier New', 'Courier', monospace; +} +a.rvts57, span.rvts57 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts57:hover +{ + color: #0000ff; +} +a.rvts58, span.rvts58 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts58:hover +{ + color: #0000ff; +} +a.rvts59, span.rvts59 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts59:hover +{ + color: #0000ff; +} +span.rvts60 +{ + font-size: 12pt; + font-weight: bold; +} +a.rvts61, span.rvts61 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts61:hover +{ + color: #0000ff; +} +a.rvts62, span.rvts62 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts62:hover +{ + color: #0000ff; +} +a.rvts63, span.rvts63 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts63:hover +{ + color: #0000ff; +} +a.rvts64, span.rvts64 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts64:hover +{ + color: #0000ff; +} +a.rvts65, span.rvts65 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts65:hover +{ + color: #0000ff; +} +a.rvts66, span.rvts66 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts66:hover +{ + color: #0000ff; +} +a.rvts67, span.rvts67 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts67:hover +{ + color: #0000ff; +} +span.rvts68 +{ + font-size: 12pt; + font-weight: bold; + text-decoration: underline; +} +a.rvts69, span.rvts69 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts69:hover +{ + color: #0000ff; +} +a.rvts70, span.rvts70 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts70:hover +{ + color: #0000ff; +} +a.rvts71, span.rvts71 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts71:hover +{ + color: #0000ff; +} +span.rvts72 +{ + font-size: 11pt; + font-weight: bold; +} +span.rvts73 +{ + font-size: 8pt; +} +a.rvts74, span.rvts74 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts74:hover +{ + color: #0000ff; +} +a.rvts75, span.rvts75 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts75:hover +{ + color: #0000ff; +} +span.rvts76 +{ + color: #0000ff; +} +span.rvts77 +{ + color: #00cc00; +} +span.rvts78 +{ + color: #ff0000; +} +span.rvts79 +{ + color: #00be00; +} +span.rvts80 +{ + color: #a08c00; +} +span.rvts81 +{ + color: #0000c3; +} +span.rvts82 +{ + color: #0082a0; +} +span.rvts83 +{ + color: #d2be00; +} +span.rvts84 +{ + color: #0a0aff; +} +span.rvts85 +{ + color: #05ff05; +} +span.rvts86 +{ + font-size: 22pt; + text-decoration: underline; +} +a.rvts87, span.rvts87 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts87:hover +{ + color: #0000ff; +} +a.rvts88, span.rvts88 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts88:hover +{ + color: #0000ff; +} +a.rvts89, span.rvts89 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts89:hover +{ + color: #0000ff; +} +span.rvts90 +{ + font-size: 18pt; + font-weight: bold; +} +a.rvts91, span.rvts91 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts91:hover +{ + color: #0000ff; +} +a.rvts92, span.rvts92 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts92:hover +{ + color: #0000ff; +} +span.rvts93 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; +} +span.rvts94 +{ + font-size: 14pt; + font-weight: bold; +} +span.rvts95 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + color: #000080; +} +span.rvts96 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + color: #333399; +} +span.rvts97 +{ + font-family: 'Courier New', 'Courier', monospace; + color: #000080; +} +span.rvts98 +{ + font-size: 16pt; + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; +} +span.rvts99 +{ + font-size: 11pt; + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; +} +span.rvts100 +{ + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; +} +span.rvts101 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + color: #000080; +} +a.rvts102, span.rvts102 +{ + font-family: 'Courier New', 'Courier', monospace; + color: #0000ff; + text-decoration: underline; +} +a.rvts102:hover +{ + color: #0000ff; +} +span.rvts103 +{ + font-size: 14pt; + font-weight: bold; +} +span.rvts104 +{ + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; + text-decoration: underline; +} +span.rvts105 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + color: #00007f; +} +span.rvts106 +{ + font-size: 14pt; + font-family: 'Courier New', 'Courier', monospace; +} +span.rvts107 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; +} +span.rvts108 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + color: #00007f; +} +span.rvts109 +{ + font-family: 'Courier New', 'Courier', monospace; + color: ; +} +span.rvts110 +{ + font-family: 'Lucida Console', 'Monaco', monospace; + text-decoration: underline; +} +span.rvts111 +{ + font-weight: bold; + text-decoration: underline; +} +span.rvts112 +{ + font-size: 11pt; + text-decoration: underline; +} +span.rvts113 +{ + font-size: 5pt; +} +span.rvts114 +{ + font-size: 5pt; + font-weight: bold; +} +/* ========== Para Styles ========== */ +p,ul,ol /* Paragraph Style */ +{ + text-align: left; + text-indent: 0px; + padding: 0px 0px 0px 0px; + margin: 0px 0px 0px 0px; +} +.rvps1 /* Centered */ +{ + text-align: center; +} +.rvps2 +{ +} +.rvps3 +{ + text-align: center; +} +.rvps4 /* Paragraph Style */ +{ + text-align: center; + border-color: #c0c0c0; + border-style: solid; + border-width: 1px; + border-right: none; + border-left: none; + padding: 2px 0px 2px 0px; + margin: 7px 0px 7px 0px; +} +.rvps5 +{ + background: #ffffff; +} +.rvps6 +{ + text-indent: 48px; +} +.rvps7 +{ + text-indent: 48px; + margin: 0px 0px 0px 48px; +} +/* ========== Lists ========== */ +.list0 {text-indent: 0px; padding: 0; margin: 0 0 0 24px; list-style-position: outside; list-style-type: disc;} +.list1 {text-indent: 0px; padding: 0; margin: 0 0 0 24px; list-style-position: outside; list-style-type: circle;} +.list2 {text-indent: 0px; padding: 0; margin: 0 0 0 24px; list-style-position: outside; list-style-type: square;} +.list3 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: circle;} +.list4 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: square;} +.list5 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: disc;} +.list6 {text-indent: 0px; padding: 0; margin: 0 0 0 24px; list-style-position: outside;} +.list7 {text-indent: 0px; padding: 0; margin: 0 0 0 36px; list-style-position: outside; list-style-type: circle;} diff --git a/web/help/css/layout.min.css b/web/help/css/layout.min.css new file mode 100644 index 00000000..5efef0ea --- /dev/null +++ b/web/help/css/layout.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */.unselectable{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.element-invisible{position:absolute !important;clip:rect(1px, 1px, 1px, 1px);overflow:hidden;height:1px}body{background-color:#fff}@media screen and (max-width: 768px){body.sm-nav-expanded{overflow:hidden}}@media screen and (max-width: 768px){body.sm-nav-expanded nav{left:0;opacity:1}}@media screen and (max-width: 768px){body.sm-nav-expanded .mask{visibility:visible;opacity:0.5}}@media screen and (max-width: 768px){body.sm-nav-expanded .header-up nav{margin-top:0}}@media screen and (min-width: 769px){body.md-nav-expanded div#main{margin-left:350px}}@media screen and (min-width: 769px){body.md-nav-expanded header{padding-left:364px}}@media screen and (min-width: 769px){body.md-nav-expanded nav{left:0;opacity:1}}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#285f8f;text-decoration:underline}header{background-color:#fff;border-bottom:1px solid #d9d9d9;box-shadow:0 1px 5px rgba(0,0,0,0.1);padding:10px 14px;position:fixed;top:0;left:0;right:0;height:64px;min-height:64px;z-index:2;display:flex;flex-wrap:nowrap;align-content:flex-start;align-items:center}@media screen and (max-width: 768px){header.slideUp.headroom--not-bottom{box-shadow:none;top:-64px}}header .hnd-toggle{background-color:transparent;border-color:transparent;margin-right:10px;padding:9px}@media screen and (min-width: 769px){header .hnd-toggle{display:none}}header .hnd-toggle .icon-bar{background-color:#666;display:block;width:22px;height:2px;border-radius:1px}header .hnd-toggle .icon-bar+.icon-bar{margin-top:4px}header h1{margin:0;flex-grow:1;font-size:19px;font-weight:500;line-height:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}header .logo{margin-left:10px;max-height:44px}nav{background-color:#f7f7f7;border:0;opacity:0;position:fixed;top:0;left:-350px;bottom:0;width:350px;z-index:3;overflow:hidden;display:flex;flex-direction:column;flex-wrap:nowrap}@media screen and (max-width: 768px){nav{box-shadow:1px 0 5px rgba(0,0,0,0.1);left:-90%;width:90% !important;margin-top:0;z-index:5}}nav .tab-tabs{border-bottom:1px solid #d9d9d9;box-shadow:0 1px 5px rgba(0,0,0,0.1);display:flex;justify-content:space-around;align-items:stretch;height:64px;min-height:64px;margin:0;padding:0}nav .tab-tabs .hnd-toggle{background-color:#eaeaea;margin:0 16px 0 14px;padding:6px 13px}nav .tab-tabs .hnd-toggle:hover{background-color:#f7f7f7}@media screen and (min-width: 769px){nav .tab-tabs .hnd-toggle{display:none}}nav .tab-tabs li{font-size:16px;height:100%;list-style:none;overflow:hidden;position:relative;text-align:center;float:none;margin-bottom:0}nav .tab-tabs li a{min-height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;align-content:stretch;text-overflow:ellipsis;cursor:pointer !important;border:0 !important;border-color:transparent !important;border-radius:0 !important;margin:0 !important;padding:0 !important;line-height:initial !important}nav .tab-tabs li .glyphicon{margin-bottom:5px}nav .tab-tabs li#nav-close{align-self:center;height:auto;min-width:70px}@media screen and (min-width: 769px){nav .tab-tabs li#nav-close{min-width:0}}nav .tab-tabs li+li{flex-grow:1}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#ddd;color:#337ab7}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#eaeaea;color:#337ab7}nav .tab-tabs>li.tab::after{content:"";background:#337ab7;height:2px;position:absolute;width:100%;left:0;bottom:0;transform:scale(0)}nav .tab-tabs>li.tab.active::after,nav .tab-tabs>li.tab:hover::after{transform:scale(1)}nav .tab-tabs>li.active>a{background-color:#f2f2f2}nav .tab-content{flex-grow:1;overflow:auto}nav .search-input{margin:7px}@media screen and (max-width: 768px){nav .search-input #input-search{font-size:16px}}nav #search-info{border-left:2px solid #ddd;display:none;margin:7px;padding:5px}@media screen and (max-width: 768px){nav #search-info{font-size:16px}}#hnd-splitter{background-color:transparent;position:fixed;top:0;left:-100px;width:8px;height:100%;touch-action:none;user-select:none;z-index:10}#hnd-splitter:hover{background-color:#ddd}@media screen and (max-width: 768px){#hnd-splitter{display:none}}.mask{background-color:#000;visibility:hidden;opacity:0;position:fixed;top:0;left:0;right:0;bottom:0;z-index:4}div#main{margin:64px 0 0 0;z-index:1}div#main>article{padding:14px}div#main>article mark{background-color:#ffff7b;padding:0}div#main>article .navigation{border-bottom:2px solid #f2f2f2;display:flex;margin-bottom:20px}div#main>article .navigation:empty{border:0}div#main>article .navigation .breadcrumb{background-color:transparent;border-radius:0;flex-grow:1;margin-bottom:0;padding:0 0 5px 0}div#main>article .navigation .breadcrumb>li::after{padding:0 5px;color:#d9d9d9;content:"/"}div#main>article .navigation .breadcrumb>li+li::before{content:none;padding:0}div#main>article .navigation .nav-arrows{flex-shrink:0;margin-bottom:4px}div#main>article .navigation .nav-arrows a{border:0;background-color:transparent;color:#333;padding:1px 6px}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#337ab7}div#main>article #topic_footer{margin-top:14px}#topic-content{padding:0}#topic-content table{border-collapse:separate}#topic-content img{max-width:100%;height:auto;vertical-align:baseline}.jstree .jstree-anchor{text-shadow:inherit}.jstree .jstree-node .jstree-clicked{background:#ddd;border-color:#aaa}.jstree .jstree-node .jstree-hovered{background:#eaeaea;border-color:#b7b7b7}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl{background-color:transparent;background-image:none;background-position:0 0}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{content:"\e250";color:#666;font-family:'Glyphicons Halflings';font-style:normal;font-size:10px}@media screen and (max-width: 768px){.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{font-size:16px}}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#337ab7}.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{content:"\e252"}.jstree .jstree-node.jstree-open>.jstree-anchor>.icon-default{background:transparent url(../vendors/helpndoc-5/icons/1.png) no-repeat center center !important}.jstree .jstree-node.jstree-closed>.jstree-anchor>.icon-default{background:transparent url(../vendors/helpndoc-5/icons/0.png) no-repeat center center !important}.jstree .jstree-node .icon-default{background:transparent url(../vendors/helpndoc-5/icons/8.png) no-repeat center center !important}.jstree .jstree-node .icon-0{background:transparent url(../vendors/helpndoc-5/icons/0.png) no-repeat center center !important}.jstree .jstree-node .icon-1{background:transparent url(../vendors/helpndoc-5/icons/1.png) no-repeat center center !important}.jstree .jstree-node .icon-2{background:transparent url(../vendors/helpndoc-5/icons/2.png) no-repeat center center !important}.jstree .jstree-node .icon-3{background:transparent url(../vendors/helpndoc-5/icons/3.png) no-repeat center center !important}.jstree .jstree-node .icon-4{background:transparent url(../vendors/helpndoc-5/icons/4.png) no-repeat center center !important}.jstree .jstree-node .icon-5{background:transparent url(../vendors/helpndoc-5/icons/5.png) no-repeat center center !important}.jstree .jstree-node .icon-6{background:transparent url(../vendors/helpndoc-5/icons/6.png) no-repeat center center !important}.jstree .jstree-node .icon-7{background:transparent url(../vendors/helpndoc-5/icons/7.png) no-repeat center center !important}.jstree .jstree-node .icon-8{background:transparent url(../vendors/helpndoc-5/icons/8.png) no-repeat center center !important}.jstree .jstree-node .icon-9{background:transparent url(../vendors/helpndoc-5/icons/9.png) no-repeat center center !important}.jstree .jstree-node .icon-10{background:transparent url(../vendors/helpndoc-5/icons/10.png) no-repeat center center !important}.jstree .jstree-node .icon-11{background:transparent url(../vendors/helpndoc-5/icons/11.png) no-repeat center center !important}.jstree .jstree-node .icon-12{background:transparent url(../vendors/helpndoc-5/icons/12.png) no-repeat center center !important}.jstree .jstree-node .icon-13{background:transparent url(../vendors/helpndoc-5/icons/13.png) no-repeat center center !important}.jstree .jstree-node .icon-14{background:transparent url(../vendors/helpndoc-5/icons/14.png) no-repeat center center !important}.jstree .jstree-node .icon-15{background:transparent url(../vendors/helpndoc-5/icons/15.png) no-repeat center center !important}.jstree .jstree-node .icon-16{background:transparent url(../vendors/helpndoc-5/icons/16.png) no-repeat center center !important}.jstree .jstree-node .icon-17{background:transparent url(../vendors/helpndoc-5/icons/17.png) no-repeat center center !important}.jstree .jstree-node .icon-18{background:transparent url(../vendors/helpndoc-5/icons/18.png) no-repeat center center !important}.jstree .jstree-node .icon-19{background:transparent url(../vendors/helpndoc-5/icons/19.png) no-repeat center center !important}.jstree .jstree-node .icon-20{background:transparent url(../vendors/helpndoc-5/icons/20.png) no-repeat center center !important}.jstree .jstree-node .icon-21{background:transparent url(../vendors/helpndoc-5/icons/21.png) no-repeat center center !important}.jstree .jstree-node .icon-22{background:transparent url(../vendors/helpndoc-5/icons/22.png) no-repeat center center !important}.jstree .jstree-node .icon-23{background:transparent url(../vendors/helpndoc-5/icons/23.png) no-repeat center center !important}.jstree .jstree-node .icon-24{background:transparent url(../vendors/helpndoc-5/icons/24.png) no-repeat center center !important}.jstree .jstree-node .icon-25{background:transparent url(../vendors/helpndoc-5/icons/25.png) no-repeat center center !important}.jstree .jstree-node .icon-26{background:transparent url(../vendors/helpndoc-5/icons/26.png) no-repeat center center !important}.jstree .jstree-node .icon-27{background:transparent url(../vendors/helpndoc-5/icons/27.png) no-repeat center center !important}.jstree .jstree-node .icon-28{background:transparent url(../vendors/helpndoc-5/icons/28.png) no-repeat center center !important}.jstree .jstree-node .icon-29{background:transparent url(../vendors/helpndoc-5/icons/29.png) no-repeat center center !important}.jstree .jstree-node .icon-30{background:transparent url(../vendors/helpndoc-5/icons/30.png) no-repeat center center !important}.jstree .jstree-node .icon-31{background:transparent url(../vendors/helpndoc-5/icons/31.png) no-repeat center center !important}.jstree .jstree-node .icon-32{background:transparent url(../vendors/helpndoc-5/icons/32.png) no-repeat center center !important}.jstree .jstree-node .icon-33{background:transparent url(../vendors/helpndoc-5/icons/33.png) no-repeat center center !important}.jstree .jstree-node .icon-34{background:transparent url(../vendors/helpndoc-5/icons/34.png) no-repeat center center !important}.jstree .jstree-node .icon-35{background:transparent url(../vendors/helpndoc-5/icons/35.png) no-repeat center center !important}.jstree .jstree-node .icon-36{background:transparent url(../vendors/helpndoc-5/icons/36.png) no-repeat center center !important}.jstree .jstree-node .icon-37{background:transparent url(../vendors/helpndoc-5/icons/37.png) no-repeat center center !important}.jstree .jstree-node .icon-38{background:transparent url(../vendors/helpndoc-5/icons/38.png) no-repeat center center !important}.jstree .jstree-node .icon-39{background:transparent url(../vendors/helpndoc-5/icons/39.png) no-repeat center center !important}.jstree .jstree-node .icon-40{background:transparent url(../vendors/helpndoc-5/icons/40.png) no-repeat center center !important}.jstree .jstree-node .icon-41{background:transparent url(../vendors/helpndoc-5/icons/41.png) no-repeat center center !important}.modal-body .relative-list{margin:0;padding:5px}.modal-body .relative-list li{list-style:none;margin:0;padding:0}@media screen and (max-width: 768px){.modal-body .relative-list li{font-size:1.1em;font-weight:700}}.modal-body .relative-list li a{color:#333;display:block;padding:5px}@media screen and (max-width: 768px){.modal-body .relative-list li a{padding:10px}}.modal-body .relative-list li a:hover{background-color:#f2f2f2;text-decoration:none} diff --git a/web/help/css/print.min.css b/web/help/css/print.min.css new file mode 100644 index 00000000..630764a7 --- /dev/null +++ b/web/help/css/print.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */header,nav,footer{display:none}div#main{margin:0}div#main>article .navigation{border-bottom:1px solid #aaa}div#main>article .navigation .nav-arrows{display:none} diff --git a/web/help/css/theme-dark-blue.min.css b/web/help/css/theme-dark-blue.min.css new file mode 100644 index 00000000..eb58d757 --- /dev/null +++ b/web/help/css/theme-dark-blue.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#3598dc}a:focus,a:hover{color:#1d6fa7}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#3598dc}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#3598dc}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#3598dc}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#3598dc}nav .tab-tabs>li.tab::after{background:#3598dc}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#3598dc}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#3598dc} diff --git a/web/help/css/theme-dark-green.min.css b/web/help/css/theme-dark-green.min.css new file mode 100644 index 00000000..2da23282 --- /dev/null +++ b/web/help/css/theme-dark-green.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#82b440}a:focus,a:hover{color:#597c2c}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#82b440}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#82b440}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#82b440}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#82b440}nav .tab-tabs>li.tab::after{background:#82b440}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#82b440}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#82b440} diff --git a/web/help/css/theme-dark-orange.min.css b/web/help/css/theme-dark-orange.min.css new file mode 100644 index 00000000..ce791959 --- /dev/null +++ b/web/help/css/theme-dark-orange.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#f40}a:focus,a:hover{color:#b33000}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#f40}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#f40}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#f40}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#f40}nav .tab-tabs>li.tab::after{background:#f40}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#f40}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#f40} diff --git a/web/help/css/theme-dark-purple.min.css b/web/help/css/theme-dark-purple.min.css new file mode 100644 index 00000000..3e3eb127 --- /dev/null +++ b/web/help/css/theme-dark-purple.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#D400FF}a:focus,a:hover{color:#9400b3}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#D400FF}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#D400FF}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#D400FF}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#D400FF}nav .tab-tabs>li.tab::after{background:#D400FF}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#D400FF}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#D400FF} diff --git a/web/help/css/theme-light-blue.min.css b/web/help/css/theme-light-blue.min.css new file mode 100644 index 00000000..795008c7 --- /dev/null +++ b/web/help/css/theme-light-blue.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#337ab7}a:focus,a:hover{color:#22527b}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#337ab7}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#337ab7}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#337ab7}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#337ab7}nav .tab-tabs>li.tab::after{background:#337ab7}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#337ab7}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#337ab7} diff --git a/web/help/css/theme-light-green.min.css b/web/help/css/theme-light-green.min.css new file mode 100644 index 00000000..7e7bbe97 --- /dev/null +++ b/web/help/css/theme-light-green.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#6f9a37}a:focus,a:hover{color:#466223}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#6f9a37}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#6f9a37}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#6f9a37}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#6f9a37}nav .tab-tabs>li.tab::after{background:#6f9a37}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#6f9a37}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#6f9a37} diff --git a/web/help/css/theme-light-orange.min.css b/web/help/css/theme-light-orange.min.css new file mode 100644 index 00000000..a754af0f --- /dev/null +++ b/web/help/css/theme-light-orange.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#B23000}a:focus,a:hover{color:#661b00}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#B23000}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#B23000}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#B23000}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#B23000}nav .tab-tabs>li.tab::after{background:#B23000}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#B23000}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#B23000} diff --git a/web/help/css/theme-light-purple.min.css b/web/help/css/theme-light-purple.min.css new file mode 100644 index 00000000..f4bb2c60 --- /dev/null +++ b/web/help/css/theme-light-purple.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#9400B2}a:focus,a:hover{color:#540066}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#9400B2}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#9400B2}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#9400B2}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#9400B2}nav .tab-tabs>li.tab::after{background:#9400B2}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#9400B2}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#9400B2} diff --git a/web/help/fceux.html b/web/help/fceux.html index b3cd7afd..ce5150b1 100644 --- a/web/help/fceux.html +++ b/web/help/fceux.html @@ -1,30 +1,304 @@ - - + + + + - - - FCEUX Help - + + + + + + + Introduction + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Introduction

+ +
+ +

+

Welcome to the FCEUX Help menu.

+


+

The following information is about how to use FCEUX, its commands, how to use FCEUX to its fullest, and the communities for which FCEUX is designed.

+


+


+

Introduction

+


+

Basic information about FCEUX and its features.

+

Overview

+

FCE Ultra Version History

+

What's Combined In FCEUX?

+


+


+

Additional Chapters

+


+

General

+

Guides for general uses of FCEUX and the FCEUX NES menu.

+


+

Config

+

Commands under FCEUX Config menu.

+


+

Tools

+

Commands under FCEUX Tools menu.

+


+

Debug

+

Commands under FCEUX Debug menu.

+


+

FAQ / Guides

+

Information regarding various concepts such as TAS, ROM Hacking, RAM Mapping.

+


+

Technical Information

+

Technical information relating to NES hardware emulation & FCEUX file formats.

+


+


+


+


+

Help menu created by adelikat.

+

Updated & maintained by AnS.

+

Information collected and/or written/edited by adelikat and AnS.

+

Minor edits of lua-related text by FatRatKnight.

+

Debugger documentation edits by rainwarrior.

+


+

+

Created with the Personal Edition of HelpNDoc: Easy EPub and documentation editor

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/fcm.html b/web/help/fcm.html index b31655a0..42da4b19 100644 --- a/web/help/fcm.html +++ b/web/help/fcm.html @@ -1,101 +1,292 @@ - - + + + + + - .fcm - - - - - - - - - - + + + + + + + + .fcm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

.fcm

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

FCE Ultra Movie File Format

-

       - Updated March 22, 2004

-


-

The FCM file format is a somewhat "joined" file format.  The first part of a FCM

-

file will contain an FCS-format state save.  After this data, the FCM-specific data

-

begins, which is being referred to from this point.

-


-


-

Currently, the only supported input scheme for a FCM is four joysticks.

-


-

The FCM data consists of a stream of joystick commands:

-


-

       dLLjjbbb

-


-

       d  = Dummy update, if set.  Used to reset frame timestamp.

-

       LL  = timestamp length, in bytes(maximum of 3 bytes).

-

       jj  = Which joystick(0-3).

-

       bbb = Which button(0-7).

-


-

       If the dummy update bit is set, a command can also have occurred.  Look at the

-

       lower 5 bits:

-

               0        =        Just a dummy update.

-

               1        =        Reset

-

               2        =        Power

-


-

       The timestamp is stored after the joystick command, in LSB-first format.  It is

-

       the number of frames since the last event.  A timestamp length of "0" is valid, to

-

       be used when several different buttons need to change state at the same time(same frame,

-

       at least).

-


-

-

Created with the Personal Edition of HelpNDoc: Create HTML Help, DOC, PDF and print manuals from 1 single source

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

.fcm

+ +
+ +

+

FCE Ultra Movie File Format

+

       - Updated March 22, 2004

+


+

The FCM file format is a somewhat "joined" file format.  The first part of a FCM

+

file will contain an FCS-format state save.  After this data, the FCM-specific data

+

begins, which is being referred to from this point.

+


+


+

Currently, the only supported input scheme for a FCM is four joysticks.

+


+

The FCM data consists of a stream of joystick commands:

+


+

       dLLjjbbb

+


+

       d  = Dummy update, if set.  Used to reset frame timestamp.

+

       LL  = timestamp length, in bytes(maximum of 3 bytes).

+

       jj  = Which joystick(0-3).

+

       bbb = Which button(0-7).

+


+

       If the dummy update bit is set, a command can also have occurred.  Look at the

+

       lower 5 bits:

+

               0        =        Just a dummy update.

+

               1        =        Reset

+

               2        =        Power

+


+

       The timestamp is stored after the joystick command, in LSB-first format.  It is

+

       the number of frames since the last event.  A timestamp length of "0" is valid, to

+

       be used when several different buttons need to change state at the same time(same frame,

+

       at least).

+


+

+

Created with the Personal Edition of HelpNDoc: Create cross-platform Qt Help files

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/fcs.html b/web/help/fcs.html index 428602d2..d9b4c45f 100644 --- a/web/help/fcs.html +++ b/web/help/fcs.html @@ -1,227 +1,418 @@ - - + + + + + - Savestate (.fcs) - - - - - - - - - - + + + + + + + + Savestate (.fcs) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

Savestate (.fcs)

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

FCE Ultra Save State Format

-

Updated:  Mar 9, 2003

-

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

-


-

FCE Ultra's save state format is now designed to be as forward and backwards

-

compatible as possible.  This is achieved through the (over)use of chunks.

-

All multiple-byte variables are stored LSB(least significant byte)-first.

-

Data types:

-


-

       (u)int8 - (un)signed 8 bit variable(also referred to as "byte")

-

       (u)int16 - (un)signed 16 bit variable

-

       (u)int32 - (un)signed 32 bit variable

-


-

-- Main File Header:

-


-

The main file header is 16-bytes in length.  The first three bytes contain

-

the string "FCS".  The next byte contains the version of FCE Ultra that saved

-

this save state.  This document only applies to version "53"(.53) and higher.

-

After the version byte, the size of the entire file in bytes(minus the 16 byte

-

main file header) is stored.  If oldversion is set to 255, the 32-bit version

-

field will be used.  In this field, a version such as 0.98.10 is stored as "9810"(decimal).

-

The rest of the header is currently unused and should be nulled out.  

-

Example of relevant parts:

-


-

       FCS <uint8 oldversion> <uint32 totalsize> <uint32 version>

-


-

-- Section Chunks:

-


-

Sections chunk headers are 5-bytes in length.  The first byte defines what

-

section it  is, the next four bytes define the total size of the section

-

(including the section chunk header).

-


-

       <uint8 section> <uint32 size>

-


-

Section definitions:

-


-

       1        -        "CPU"

-

       2        -        "CPUC"

-

       3        -        "PPU"

-

       4        -        "CTLR"

-

       5        -        "SND"

-

       16        -        "EXTRA"

-


-

-- Subsection Chunks

-


-

Subsection chunks are stored within section chunks.  They contain the actual

-

state data.  Each subsection chunk is composed of an 8-byte header and the data.

-

The header contains a description(a name) and the size of the data contained

-

in the chunk:

-

               <uint8 description[4]> <uint32 size>

-


-

The name is a four-byte string.  It does not need to be null-terminated.

-

If the string is less than four bytes in length, the remaining unused bytes

-

must be null.

-


-

-- Subsection Chunk Description Definitions

-


-

Note that not all subsection chunk description definitions listed below

-

are guaranteed to be in the section chunk.  It's just a list of what CAN

-

be in a section chunk.  This especially applies to the "EXTRA" subsection.

-


-

---- Section "CPU"

-


-

       Name:        Type:                Description:

-

       

-

       PC        uint16                Program Counter

-

       A        uint8                Accumulator

-

       P        uint8                Processor status register

-

       X        uint8                X register

-

       Y        uint8                Y register

-

       S        uint8                Stack pointer

-

       RAM        uint8[0x800]        2KB work RAM

-


-

---- Section "CPUC" (emulator specific)

-


-

       Name:        Type:                Description:

-


-

       JAMM        uint8                Non-zero value if CPU in a "jammed" state

-

       IRQL        uint8                Non-zero value if IRQs are to be generated constantly

-

       ICoa        int32                Temporary cycle counter

-

       ICou        int32                Cycle counter

-


-

---- Section "PPU"

-


-

       Name:        Type:                Description:

-


-

       NTAR        uint8[0x800]        2 KB of name/attribute table RAM

-

       PRAM        uint8[32]        32 bytes of palette index RAM

-

       SPRA        uint8[0x100]        256 bytes of sprite RAM

-

       PPU        uint8[4]        Last values written to $2000 and $2001, the PPU

-

                               status register, and the last value written to

-

                               $2003.

-

       XOFF        uint8                Tile X-offset.

-

       VTOG        uint8                Toggle used by $2005 and $2006.

-

       RADD        uint16                PPU Address Register(address written to/read from

-

                               when $2007 is accessed).

-

       TADD        uint16                PPU Address Register

-

       VBUF        uint8                VRAM Read Buffer

-

       PGEN        uint8                PPU "general" latch.  See Ki's document.

-


-

---- Section "CTLR" (somewhat emulator specific)

-


-

       Name:        Type:                Description:

-


-

       J1RB        uint8                Bit to be returned when first joystick is read.

-

       J2RB        uint8                Bit to be returned when second joystick is read.

-


-

---- Section "SND" (somewhat emulator specific)

-


-

       NREG        uint16                Noise LFSR.

-

       P17        uint8                Last byte written to $4017.

-

       PBIN        uint8                DMC bit index.

-

       PAIN        uint32                DMC address index(from $8000).

-

       PSIN        uint32                DMC length counter(how many bytes left

-

                               to fetch).

-


-

       <to be finished>

-


-

---- Section "EXTRA" (varying emulator specificness)

-


-

       For iNES-format games(incomplete, and doesn't apply to every game):

-


-

       Name:        Type:                Description:

-


-

       WRAM        uint8[0x2000]        8KB of WRAM at $6000-$7fff

-

       MEXR        uint8[0x8000]        (very emulator specific)

-

       CHRR        uint8[0x2000]        8KB of CHR RAM at $0000-$1fff(in PPU address space).

-

       EXNR        uint8[0x800]        Extra 2KB of name/attribute table RAM.

-

       MPBY        uint8[32]        (very emulator specific)

-

       MIRR        uint8                Current mirroring:

-

                                       0 = "Horizontal"

-

                                       1 = "Vertical"

-

                                       $10 = Mirror from $2000

-

                                       $11 = Mirror from $2400

-

       IRQC        uint32                Generic IRQ counter

-

       IQL1        uint32                Generic IRQ latch

-

       IQL2        uint32                Generic IRQ latch

-

       IRQA        uint8                Generic IRQ on/off register.

-

       PBL        uint8[4]                List of 4 8KB ROM banks paged in at $8000-$FFFF

-

       CBL        uint8[8]                List of 8 1KB VROM banks page in at $0000-$1FFF(PPU).

-


-

       For FDS games(incomplete):

-


-

       Name:        Type:                Description:

-


-

       DDT<x>  uint8[65500]    Disk data for side x(0-3).

-

       FDSR        uint8[0x8000]        32 KB of work RAM

-

       CHRR        uint8[0x2000]        8 KB of CHR RAM

-

       IRQC        uint32                IRQ counter

-

       IQL1        uint32                IRQ latch

-

       IRQA        uint8                IRQ on/off.

-


-

       WAVE        uint8[64]        Carrier waveform data.

-

       MWAV        uint8[32]        Modulator waveform data.

-

       AMPL        uint8[2]                Amplitude data.

-


-

-

Created with the Personal Edition of HelpNDoc: Create HTML Help, DOC, PDF and print manuals from 1 single source

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

Savestate (.fcs)

+ +
+ +

+

FCE Ultra Save State Format

+

 Updated:  Mar 9, 2003

+

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

+


+

FCE Ultra's save state format is now designed to be as forward and backwards

+

compatible as possible.  This is achieved through the (over)use of chunks.

+

All multiple-byte variables are stored LSB(least significant byte)-first.

+

Data types:

+


+

       (u)int8 - (un)signed 8 bit variable(also referred to as "byte")

+

       (u)int16 - (un)signed 16 bit variable

+

       (u)int32 - (un)signed 32 bit variable

+


+

-- Main File Header:

+


+

The main file header is 16-bytes in length.  The first three bytes contain

+

the string "FCS".  The next byte contains the version of FCE Ultra that saved

+

this save state.  This document only applies to version "53"(.53) and higher.

+

After the version byte, the size of the entire file in bytes(minus the 16 byte

+

main file header) is stored.  If oldversion is set to 255, the 32-bit version

+

field will be used.  In this field, a version such as 0.98.10 is stored as "9810"(decimal).

+

The rest of the header is currently unused and should be nulled out.  

+

Example of relevant parts:

+


+

       FCS <uint8 oldversion> <uint32 totalsize> <uint32 version>

+


+

-- Section Chunks:

+


+

Sections chunk headers are 5-bytes in length.  The first byte defines what 

+

section it  is, the next four bytes define the total size of the section

+

(including the section chunk header).

+


+

       <uint8 section> <uint32 size>

+


+

Section definitions:

+


+

       1        -        "CPU"

+

       2        -        "CPUC"

+

       3        -        "PPU"

+

       4        -        "CTLR"

+

       5        -        "SND"

+

       16        -        "EXTRA"

+


+

-- Subsection Chunks

+


+

Subsection chunks are stored within section chunks.  They contain the actual

+

state data.  Each subsection chunk is composed of an 8-byte header and the data.

+

The header contains a description(a name) and the size of the data contained 

+

in the chunk:

+

               <uint8 description[4]> <uint32 size>

+


+

The name is a four-byte string.  It does not need to be null-terminated.

+

If the string is less than four bytes in length, the remaining unused bytes

+

must be null.

+


+

-- Subsection Chunk Description Definitions

+


+

Note that not all subsection chunk description definitions listed below

+

are guaranteed to be in the section chunk.  It's just a list of what CAN

+

be in a section chunk.  This especially applies to the "EXTRA" subsection.

+


+

---- Section "CPU"

+


+

       Name:        Type:                Description:

+

       

+

       PC        uint16                Program Counter

+

       A        uint8                Accumulator

+

       P        uint8                Processor status register

+

       X        uint8                X register

+

       Y        uint8                Y register

+

       S        uint8                Stack pointer

+

       RAM        uint8[0x800]        2KB work RAM

+


+

---- Section "CPUC" (emulator specific)

+


+

       Name:        Type:                Description:

+


+

       JAMM        uint8                Non-zero value if CPU in a "jammed" state

+

       IRQL        uint8                Non-zero value if IRQs are to be generated constantly

+

       ICoa        int32                Temporary cycle counter

+

       ICou        int32                Cycle counter

+


+

---- Section "PPU"

+


+

       Name:        Type:                Description:

+


+

       NTAR        uint8[0x800]        2 KB of name/attribute table RAM

+

       PRAM        uint8[32]        32 bytes of palette index RAM

+

       SPRA        uint8[0x100]        256 bytes of sprite RAM

+

       PPU        uint8[4]        Last values written to $2000 and $2001, the PPU

+

                               status register, and the last value written to

+

                               $2003.

+

       XOFF        uint8                Tile X-offset.

+

       VTOG        uint8                Toggle used by $2005 and $2006.

+

       RADD        uint16                PPU Address Register(address written to/read from

+

                               when $2007 is accessed).

+

       TADD        uint16                PPU Address Register

+

       VBUF        uint8                VRAM Read Buffer

+

       PGEN        uint8                PPU "general" latch.  See Ki's document.

+


+

---- Section "CTLR" (somewhat emulator specific)

+


+

       Name:        Type:                Description:

+


+

       J1RB        uint8                Bit to be returned when first joystick is read.

+

       J2RB        uint8                Bit to be returned when second joystick is read.

+


+

---- Section "SND" (somewhat emulator specific)

+


+

       NREG        uint16                Noise LFSR.

+

       P17        uint8                Last byte written to $4017.

+

       PBIN        uint8                DMC bit index.

+

       PAIN        uint32                DMC address index(from $8000).

+

       PSIN        uint32                DMC length counter(how many bytes left 

+

                               to fetch).

+


+

       <to be finished>

+


+

---- Section "EXTRA" (varying emulator specificness)

+


+

       For iNES-format games(incomplete, and doesn't apply to every game):

+


+

       Name:        Type:                Description:

+


+

       WRAM        uint8[0x2000]        8KB of WRAM at $6000-$7fff

+

       MEXR        uint8[0x8000]        (very emulator specific)

+

       CHRR        uint8[0x2000]        8KB of CHR RAM at $0000-$1fff(in PPU address space).

+

       EXNR        uint8[0x800]         Extra 2KB of name/attribute table RAM.

+

       MPBY        uint8[32]        (very emulator specific)

+

       MIRR        uint8                Current mirroring:

+

                                       0 = "Horizontal"

+

                                       1 = "Vertical"

+

                                       $10 = Mirror from $2000

+

                                       $11 = Mirror from $2400

+

       IRQC        uint32                Generic IRQ counter

+

       IQL1        uint32                Generic IRQ latch

+

       IQL2        uint32                Generic IRQ latch

+

       IRQA        uint8                Generic IRQ on/off register.

+

       PBL        uint8[4]                List of 4 8KB ROM banks paged in at $8000-$FFFF

+

       CBL        uint8[8]                List of 8 1KB VROM banks page in at $0000-$1FFF(PPU).

+


+

       For FDS games(incomplete):

+


+

       Name:        Type:                Description:

+


+

       DDT<x>  uint8[65500]    Disk data for side x(0-3).

+

       FDSR        uint8[0x8000]        32 KB of work RAM

+

       CHRR        uint8[0x2000]        8 KB of CHR RAM

+

       IRQC        uint32                IRQ counter

+

       IQL1        uint32                IRQ latch

+

       IRQA        uint8                IRQ on/off.

+


+

       WAVE        uint8[64]        Carrier waveform data.

+

       MWAV        uint8[32]        Modulator waveform data.

+

       AMPL        uint8[2]                Amplitude data.

+


+

+

Created with the Personal Edition of HelpNDoc: Benefits of a Help Authoring Tool

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/fm2.html b/web/help/fm2.html index 508e5fb5..b7ad5e75 100644 --- a/web/help/fm2.html +++ b/web/help/fm2.html @@ -1,273 +1,464 @@ - - + + + + + - .fm2 - - - - - - - - - - + + + + + + + + .fm2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
-
-

.fm2

- - -
-
- Parent - - Previous - - Next - -
-
-
-
- -

-

FCEUX Movie File format

-


-


-

FCEUX uses a new movie file format - .fm2.

-


-

This differs from the previous FCE Ultra movie format (.fcm) in the following ways:

- -


-


-

Format

-


-

FM2 consists of two parts: Header and Input Log.

-

The header is always in ASCII plain text format. It consists of several key-value pairs.

-

The input log section can be identified by it starting with a | (pipe).

-

The input log section can be either in ASCII plain text format or in binary format.

-

The input log section terminates at EOF, unless the length key is specified in header.

-

Newlines may be \r\n or \n.

-


-


-

Header

-


-

Key-value pairs consist of a key identifier, followed by a space separator, followed by the value text.

-

Value text is always terminated by a newline, which the value text does not include.

-

The value text is parsed differently depending on the type of the key.

-

The key-value pairs may be in any order, except that the first key must be version.

-


-

Integer keys (also used for booleans, with a 1 for true and 0 for false) must have a value that can be stored as int32:

-


-

- version (required) - the version of the movie file format; for now it is always 3

-


-

- emuVersion (required) - the version of the emulator used to produce the movie

-


-

- rerecordCount (optional) - the rerecord count

-


-

- palFlag (bool) (optional) - true if the movie uses PAL timing

-


-

- NewPPU (bool) (optional) - true if the movie uses New PPU

-


-

- FDS (bool) (optional) - true if movie was recorded on a Famicom Disk System (FDS) game

-


-

- fourscore (bool) - true if a fourscore was used. If fourscore is not used, then port0 and port1 are required

-


-

- port0 - indicates the type of input device attached to the port 0. Supported values are:

-

    SI_NONE = 0

-

    SI_GAMEPAD = 1

-

    SI_ZAPPER = 2

-


-

- port1 - indicates the type of input device attached to the port 1. Supported values are:

-

    SI_NONE = 0

-

    SI_GAMEPAD = 1

-

    SI_ZAPPER = 2

-


-

- port2 (required) - indicates the type of the FCExp port device which was attached. Supported values are:

-

    SIFC_NONE = 0

-


-

- binary (bool) (optional) - true if input log is stored in binary format

-


-

- length (optional) - movie size (number of frames in the input log). If this key is specified and the number is >= 0, the input log ends after specified number of records, and any remaining data should not be parsed. This key is used in fm3 format to allow storing extra data after the end of input log

-


-


-

String keys have values that consist of the remainder of the key-value pair line. As a consequence, string values cannot contain newlines.

-


-

- romFilename (required) - the name of the file used to record the movie

-


-

- comment (optional) - simply a memo

- -

Example:

- -


-

- subtitle (optional) - a message that will be displayed on screen when movie is played back (unless Subtitles are turned off, see Movie options)

- -

Example:

- -

At frame 1000 the words "Level Two" will be displayed on the screen

-


-

- guid (required) - a unique identifier for a movie, generated when the movie is created, which is used when loading a savestate to make sure it belongs to the current movie

-

GUID keys have a value which is in the standard guide format: 452DE2C3-EF43-2FA9-77AC-0677FC51543B

-


-

- romChecksum (required) - the base64 of the hexified MD5 hash of the ROM which was used to record the movie

-


-

- savestate (optional) - a fcs savestate blob, in case a movie was recorded from savestate  

-

Hex string keys (used for binary blobs) have a value that is like 0x0123456789ABCDEF...

-


-


-

Input log

-


-

The input log section consists of movie records either in the form of text lines or in the form of binary data.

-


-


-

Text format (default format):

-


-

Every frame of the movie is represented by line of text beginning and ending with a | (pipe).

-

The fields in the line are as follows, except when fourscore is used.

-

|commands|port0|port1|port2|

-


-

Field commands is a variable length decimal integer which is interpreted as a bit field corresponding to miscellaneous input states which are valid at the start of the frame. Current values for this are:

- -


-

The format of port0, port1, port2 depends on which types of devices were attached.

-


-

SI_GAMEPAD:

- -


-

SI_ZAPPER:

- -

XXX: %03d, the x position of the mouse

-

YYY: %03d, the y position of the mouse

-

B: %1d, 1 if the mouse button is pressed; 0 if not

-

Q: %1d, an internal value used by the emulator's zapper code

-

Z: %d, a variable-length decimal integer; an internal value used by the emulator's zapper code

-


-

SI_NONE:

- -


-

If a fourscore is used, then port0 and port1 are irrelevant and ignored.

-

The input types must all be gamepads, and each input log record must be in the following format:

-

|commands|RLDUTSBA|RLDUTSBA|RLDUTSBA|RLDUTSBA|port2|

-

{commands, player1, player2, player3, player4, port2}

-


-


-

Binary format:

-


-

Input log section starts with a | (pipe).

-

Every frame of the movie is represented by a record of a fixed length which can be determined by the devices on port0 and port1.

-


-

The first byte of each record stores "commands" bit field.

- -


-

The remaining bytes in the record depend on which types of devices are attached to port0 and port1.

-


-

SI_GAMEPAD:

- -


-

SI_ZAPPER:

- -


-

SI_NONE:

- -


-

If a fourscore is used, then port0 and port1 are irrelevant and ignored. 4 bytes are added to the size of record. The bits of the 1st byte represent the state of buttons of the 1st joypad (bit0 = A, bit1 = B, bit2 = Select, bit3 = sTart, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right); bits of the 2nd byte represent the state of buttons of the 2nd joypad, and so on.

-


-


-
-

Notes:

-


-

A. All movies start from power-on, unless a savestate key-value is present.

-


-

B. The emulator uses these framerate constants

-

 - NTSC: 1008307711 /256/65536 = 60.099822938442230224609375

-

 - PAL : 838977920  /256/65536 = 50.00698089599609375

-


-


-


-

-

Created with the Personal Edition of HelpNDoc: Create iPhone web-based documentation

-
- - - - + + + +
+ +

FCEUX Help

+ +
+ + + +
+ +
+
+ + + + + + +

.fm2

+ +
+ +

+

FCEUX Movie File format

+


+


+

FCEUX uses a new movie file format - .fm2.

+


+

This differs from the previous FCE Ultra movie format (.fcm) in the following ways:

+
    +
  • It is text based by default; allowing easy movie editing/splicing
  • +
  • An imbedded GUID so FCEUX can tell if a savestate belongs to a movie file
  • +
  • Movies recorded from Start (Power-on) no longer have a redundant savestate
  • +
  • Contains mouse input for recording the Zapper & Arkanoid Paddle
  • +
+


+


+

Format

+


+

FM2 consists of two parts: Header and Input Log.

+

The header is always in ASCII plain text format. It consists of several key-value pairs.

+

The input log section can be identified by it starting with a | (pipe).

+

The input log section can be either in ASCII plain text format or in binary format.

+

The input log section terminates at EOF, unless the length key is specified in header.

+

Newlines may be \r\n or \n.

+


+


+

Header

+


+

Key-value pairs consist of a key identifier, followed by a space separator, followed by the value text.

+

Value text is always terminated by a newline, which the value text does not include.

+

The value text is parsed differently depending on the type of the key.

+

The key-value pairs may be in any order, except that the first key must be version.

+


+

Integer keys (also used for booleans, with a 1 for true and 0 for false) must have a value that can be stored as int32:

+


+

 - version (required) - the version of the movie file format; for now it is always 3

+


+

 - emuVersion (required) - the version of the emulator used to produce the movie

+


+

 - rerecordCount (optional) - the rerecord count

+


+

 - palFlag (bool) (optional) - true if the movie uses PAL timing

+


+

 - NewPPU (bool) (optional) - true if the movie uses New PPU

+


+

 - FDS (bool) (optional) - true if movie was recorded on a Famicom Disk System (FDS) game

+


+

 - fourscore (bool) - true if a fourscore was used. If fourscore is not used, then port0 and port1 are required

+


+

 - port0 - indicates the type of input device attached to the port 0. Supported values are:

+

     SI_NONE = 0

+

     SI_GAMEPAD = 1

+

     SI_ZAPPER = 2

+


+

 - port1 - indicates the type of input device attached to the port 1. Supported values are:

+

     SI_NONE = 0

+

     SI_GAMEPAD = 1

+

     SI_ZAPPER = 2

+


+

 - port2 (required) - indicates the type of the FCExp port device which was attached. Supported values are:

+

     SIFC_NONE = 0

+


+

 - binary (bool) (optional) - true if input log is stored in binary format

+


+

 - length (optional) - movie size (number of frames in the input log). If this key is specified and the number is >= 0, the input log ends after specified number of records, and any remaining data should not be parsed. This key is used in fm3 format to allow storing extra data after the end of input log

+


+


+

String keys have values that consist of the remainder of the key-value pair line. As a consequence, string values cannot contain newlines.

+


+

 - romFilename (required) - the name of the file used to record the movie

+


+

 - comment (optional) - simply a memo

+
    +
  • by convention, the first token in the comment value is the subject of the comment
  • +
  • by convention, subsequent comments with the same subject should have their ordering preserved and may be used to approximate multi-line comments
  • +
  • by convention, the author of the movie should be stored in comment(s) with a subject of: author
  • +
+

Example:

+
    +
  • comment author adelikat
  • +
+


+

 - subtitle (optional) - a message that will be displayed on screen when movie is played back (unless Subtitles are turned off, see Movie options)

+
    +
  • by convention, subtitles begin with the word "subtitle"
  • +
  • by convention, an integer value following the word "subtitle" indicates the frame that the subtitle will be displayed
  • +
  • by convention, any remaining text after the integer is considered to be the string displayed
  • +
+

Example:

+
    +
  • subtitle 1000 Level Two
  • +
+

At frame 1000 the words "Level Two" will be displayed on the screen

+


+

 - guid (required) - a unique identifier for a movie, generated when the movie is created, which is used when loading a savestate to make sure it belongs to the current movie

+

GUID keys have a value which is in the standard guide format: 452DE2C3-EF43-2FA9-77AC-0677FC51543B

+


+

 - romChecksum (required) - the base64 of the hexified MD5 hash of the ROM which was used to record the movie

+


+

 - savestate (optional) - a fcs savestate blob, in case a movie was recorded from savestate  

+

Hex string keys (used for binary blobs) have a value that is like 0x0123456789ABCDEF...

+


+


+

Input log

+


+

The input log section consists of movie records either in the form of text lines or in the form of binary data.

+


+


+

Text format (default format):

+


+

Every frame of the movie is represented by line of text beginning and ending with a | (pipe).

+

The fields in the line are as follows, except when fourscore is used.

+

|commands|port0|port1|port2|

+


+

Field commands is a variable length decimal integer which is interpreted as a bit field corresponding to miscellaneous input states which are valid at the start of the frame. Current values for this are:

+
    +
  • 1 = Soft Reset
  • +
  • 2 = Hard Reset (Power)
  • +
  • 4 = FDS Disk Insert
  • +
  • 8 = FDS Disk Select
  • +
  • 16 = VS Insert Coin
  • +
+


+

The format of port0, port1, port2 depends on which types of devices were attached.

+


+

SI_GAMEPAD:

+
    +
  • the field consists of eight characters which constitute a bit field
  • +
  • any character other than ' ' or '.' means that the button was pressed
  • +
  • by convention, the following mnemonics are used in a column to remind us of which button corresponds to which column: RLDUTSBA (Right, Left, Down, Up, sTart, Select, B, A)
  • +
+


+

SI_ZAPPER:

+
    +
  • XXX YYY B Q Z
  • +
+

XXX: %03d, the x position of the mouse

+

YYY: %03d, the y position of the mouse

+

B: %1d, 1 if the mouse button is pressed; 0 if not

+

Q: %1d, an internal value used by the emulator's zapper code

+

Z: %d, a variable-length decimal integer; an internal value used by the emulator's zapper code

+


+

SI_NONE:

+
    +
  • the field must be empty
  • +
+


+

If a fourscore is used, then port0 and port1 are irrelevant and ignored.

+

The input types must all be gamepads, and each input log record must be in the following format:

+

|commands|RLDUTSBA|RLDUTSBA|RLDUTSBA|RLDUTSBA|port2|

+

{commands, player1, player2, player3, player4, port2}

+


+


+

Binary format:

+


+

Input log section starts with a | (pipe).

+

Every frame of the movie is represented by a record of a fixed length which can be determined by the devices on port0 and port1.

+


+

The first byte of each record stores "commands" bit field.

+
    +
  • bit 0 = Soft Reset
  • +
  • bit 1 = Hard Reset (Power)
  • +
  • bit 2 = FDS Disk Insert
  • +
  • bit 3 = FDS Disk Select
  • +
  • bit 4 = VS Insert Coin
  • +
+


+

The remaining bytes in the record depend on which types of devices are attached to port0 and port1.

+


+

SI_GAMEPAD:

+
    +
  • 1 byte added to the size of record
  • +
  • bits of the byte represent the state of buttons (bit0 = A, bit1 = B, bit2 = Select, bit3 = sTart, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right). If the bit is set, respective button is considered to be pressed, if the bit is clear, the button is not pressed
  • +
+


+

SI_ZAPPER:

+
    +
  • 12 bytes added to the size of record
  • +
  • 1st byte - the x position of the mouse
  • +
  • 2nd byte - the y position of the mouse
  • +
  • 3rd byte - 1 if the mouse button is pressed; 0 if not
  • +
  • 4th byte - an internal value used by the emulator's zapper code
  • +
  • bytes 5-12 (uint64) - an internal value used by the emulator's zapper code
  • +
+


+

SI_NONE:

+
    +
  • 0 bytes added to the size of record
  • +
+


+

If a fourscore is used, then port0 and port1 are irrelevant and ignored. 4 bytes are added to the size of record. The bits of the 1st byte represent the state of buttons of the 1st joypad (bit0 = A, bit1 = B, bit2 = Select, bit3 = sTart, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right); bits of the 2nd byte represent the state of buttons of the 2nd joypad, and so on.

+


+


+
+

Notes:

+


+

A. All movies start from power-on, unless a savestate key-value is present.

+


+

B. The emulator uses these framerate constants

+

  - NTSC: 1008307711 /256/65536 = 60.099822938442230224609375

+

  - PAL : 838977920  /256/65536 = 50.00698089599609375

+


+


+


+

+

Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

+ +
+ + +
+
+ + + +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/js/app.min.js b/web/help/js/app.min.js new file mode 100644 index 00000000..23236079 --- /dev/null +++ b/web/help/js/app.min.js @@ -0,0 +1,6 @@ +"use strict";/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */ +var __extends=this&&this.__extends||function(){var e=function(t,o){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])})(t,o)};return function(t,o){function n(){this.constructor=t}e(t,o),t.prototype=null===o?Object.create(o):(n.prototype=o.prototype,new n)}}(),Exception=function(e){function t(t){var o=e.call(this,t)||this;return o.message=t,o.name="Exception",o.message=t,o}return __extends(t,e),t.prototype.toString=function(){return"["+this.name+']: "'+this.message+'"'},t}(Error),EInvalidHtmlElement=function(e){function t(t){var o=e.call(this,t)||this;return o.message=t,o.name="EInvalidHtmlElement",o}return __extends(t,e),t}(Exception),Hnd;!function(e){var t=function(){function e(){}return e}();e.AppOptions=t;var o=function(){function e(){}return e}();e.AppEvents=o;var n=function(){function e(e){this.DEFAULTS={animationDelay:200,elHeadroom:"header",elMask:".mask",elModal:"#hndModal",elSearchForm:"#search-form",elSearchInfo:"#search-info",elSearchInput:"#input-search",elToggler:".hnd-toggle",elTopicContainer:"article",elTopicContent:"#topic-content",elTreeContainers:".tree-container",elTreeSearch:"#search-tree",classNavExpandedSmall:"sm-nav-expanded",classNavExpandedMedium:"md-nav-expanded"},this.EVENTS={onTopicChanged:null},this.TRANSLATIONS={"Search term too short":"Search term too short","No results":"No results","Please enter 3 or more characters":"Please enter 3 or more characters","Word list not ready yet. Please wait until the word list is fully downloaded":"Word list not ready yet. Please wait until the word list is fully downloaded","Incorrect or corrupt search data. Please check your HelpNDoc template":"Incorrect or corrupt search data. Please check your HelpNDoc template","Related topics...":"Related topics...","Loading...":"Loading...",Close:"Close"},this.options=$.extend({},this.DEFAULTS,e),this.Init()}return e.prototype._=function(e){var t=this.TRANSLATIONS[e];return t||e},e.prototype.doOnJsTreeError=function(e,t){console.error("JSTree Error",t);var o=e.find(".jstree-loading");o&&(t.error&&"ajax"==t.error?o.html('Loading Error: Please make sure your web-server is correctly configured to serve JSON files. Learn more...'):o.html("Error: please check your web-developer console for more information."))},e.prototype.doOnTopicChanged=function(e){this.EVENTS.onTopicChanged&&("string"==typeof e&&""!==e||(e=$(this.options.elTopicContent).data("hnd-id")+".html"),this.EVENTS.onTopicChanged(e))},e.prototype.doProcessParameters=function(){var e=URI(location.href),t=e.search(!0);t.tab&&""!=t.tab&&$("#tab-"+t.tab).tab("show"),t.search&&void 0!==t.search&&""!=t.search&&(this.$elSearchInput.val(t.search),this.$elSearchInput.keyup(),this.$elSearchForm.submit())},e.prototype.fixURI=function(e){return e.replace(/\%u00A0/g,"%20")},e.prototype.getAnchor=function(){return window.location.hash.substr(1)},e.prototype.isExternalLink=function(e){var t=function(e){return 0===e.indexOf("//")&&(e=location.protocol+e),e.toLowerCase().replace(/([a-z])?:\/\//,"$1").split("/")[0]};return(e.indexOf(":")>-1||e.indexOf("//")>-1)&&t(location.href)!==t(e)||-1==["htm","html"].indexOf(new URI(e).suffix().toLowerCase())},e.prototype.DoShowExternalUrl=function(e,t,o){window.open(t,o)},e.prototype.DoShowTopic=function(e,t,o){var n=this;this.$elTopicContainer.load(o+" "+this.options.elTopicContent,function(e,r,i){var a=$(n.options.elTopicContent),s=a.data("hnd-id");if(window.history.pushState({id:s,title:t},t,o),"undefined"!=typeof ga&&ga)try{if(void 0!==ga.getAll&&ga.getAll&&ga.getAll()[0]){ga.getAll()[0].send("pageview",location.pathname)}else ga("send","pageview",location.pathname)}catch(e){console.error("[HND-APP] An error occurred while using Google Analytics tracking code =>",e.toString())}n.SelectTopicInToc(s,t,!1),n.DoScrollToAnchorIfNeeded(),n.DoHighlightText(n.searchTerm),imageMapResize(),n.doOnTopicChanged(o)})},e.prototype.DoHandleLink=function(e,t,o,n,r){"_blank"==n||this.isExternalLink(o)||!0===r?this.DoShowExternalUrl(t,o,n):this.DoShowTopic(e,t,o)},e.prototype.DoHighlightText=function(e){try{this.$elTopicContainer.unmark(),e&&""!==e&&this.$elTopicContainer.mark(e,{accuracy:"complementary",diacritics:!1})}catch(e){console.error("[HND-APP] An error occurred while highlighting the search term =>",e.toString())}},e.prototype.DoScrollToAnchorIfNeeded=function(){var e=decodeURIComponent(this.getAnchor());if(""!==e){var t=$("a[name='"+e+"']");if(t&&t.length||(t=$("a[name='"+e.toLowerCase()+"']")),t&&void 0!==t&&t.offset&&t.offset()){var o=this.$elHeadroom.position().top<0?0:this.$elHeadroom.outerHeight(!0)+5;$("html,body").animate({scrollTop:t.offset().top-o},"fast")}else console.error("[HND-APP] Unkonwn or invalid anchor =>",e)}else $("html,body").animate({scrollTop:0},"fast")},e.prototype.InitHeadRoom=function(){if(this.$elHeadroom=$(this.options.elHeadroom),!this.$elHeadroom.length)throw new EInvalidHtmlElement("Invalid headroom element ["+this.options.elHeadroom+"]");new Headroom(this.$elHeadroom.get(0),{offset:100,tolerance:5,classes:{initial:"animated",pinned:"slideDown",unpinned:"slideUp"},onUnpin:function(){$("body").addClass("header-up")},onPin:function(){$("body").removeClass("header-up")}}).init()},e.prototype.InitMask=function(){var e=this;this.$elMask=$(this.options.elMask),this.$elMask.on("click",function(t){var o=e.$elMask.data("toggle");o&&$("body").removeClass(o)})},e.prototype.InitModal=function(){this.$elModal=$(this.options.elModal),this.$elModal.find(".modal-title").html(this._("Related topics...")),this.$elModal.find(".modal-btn-close").html(this._("Close")),this.$elModal.modal({show:!1})},e.prototype.InitResponsiveClasses=function(){function e(){var e="",o=$(window).width();if(o<768?e="mode-xs":o<992?e="mode-sm":o<1200?e="mode-md":o>=1200&&(e="mode-lg"),e!=t){if($("body").removeClass(["mode-xs","mode-sm","mode-md","mode-lg"]).addClass(e),"mode-xs"==e)$("header").css("padding-left",""),$("#main").css("margin-left",""),$("#panel-left").css("width","");else if("mode-xs"==t){var n=$("#hnd-splitter").offset().left;$("header").css("padding-left",n+14),$("#main").css("margin-left",n),$("#panel-left").css("width",n)}t=e}}var t="";e(),$(window).on("resize",function(){e()})},e.prototype.InitSplitter=function(){var e=0,t=parseInt($("nav").css("width"),10),o=$("#hnd-splitter");o&&o.length&&interact("#hnd-splitter").draggable({cursorChecker:function(){return"ew-resize"},startAxis:"xy",lockAxis:"x",listeners:{move:function(t){e+=t.dx,t.target.style.transform="translateX("+e+"px)"},end:function(o){$("header").css("padding-left",t+14+e),$("#main").css("margin-left",t+e),$("#panel-left").css("width",t+e)}}})},e.prototype.InitSearchEngine=function(){this.searchEngine=new HndJsSe},e.prototype.InitSearchForm=function(){var e=this;this.$elTreeSearch=$(this.options.elTreeSearch).first(),this.$elSearchForm=$(this.options.elSearchForm),this.$elSearchInfo=$(this.options.elSearchInfo),this.$elSearchInput=$(this.options.elSearchInput),this.$elSearchInfo.html(this._("Please enter 3 or more characters")+"."),this.$elSearchInfo.show(),this.$elSearchInput.on("keyup",function(t){e.searchTerm=String(e.$elSearchInput.val()),e.DoHighlightText(e.searchTerm)}),this.$elSearchForm.on("submit",function(t){t.preventDefault();var o=e.$elTreeSearch.jstree(!0),n=$(t.target).find('input[type="text"]').first(),r=String(n.val());if(e.$elSearchInfo.hide(),o.delete_node(e.$elTreeSearch.find("li").toArray()),r.length<3)e.$elSearchInfo.html(e._("Search term too short")+". "+e._("Please enter 3 or more characters")+"."),e.$elSearchInfo.show();else if(window.bSearchDataLoaded)if(oWl){e.searchEngine.ParseInput(r);var i=e.searchEngine.PerformSearch(oWl);if(0==i.length)e.$elSearchInfo.html(e._("No results")+". "+e._("Please enter 3 or more characters")+"."),e.$elSearchInfo.show();else for(var a="",s=0;s'+c[d].title+"";h+="",e.$elModal.find(".modal-body").html(h),e.$elModal.modal("show")}else $("body").removeClass("sm-nav-expanded"),e.DoHandleLink(a,s,i,l,!1)}}).on("ready.jstree",function(t,n){e.SelectTopicInToc("","",!0);var r=parseInt($(o).data("openlvl"),10);r&&e.OpenTreeToLevel($(o),r)}).jstree({core:{animation:e.options.animationDelay,check_callback:$(o).is($(e.options.elTreeSearch)),multiple:!1,strings:{"Loading ...":e._("Loading...")},themes:{dots:!1,responsive:!0},data:r,error:function(t){e.doOnJsTreeError($(o),t)}},types:{default:{icon:"icon-default"}},plugins:["types"]})})},e.prototype.InitHistory=function(){var e=this;window.onpopstate=function(t){e.$elTopicContainer.load(window.location+" "+e.options.elTopicContent,function(t,o,n){e.SelectTopicInToc("","",!1),e.DoScrollToAnchorIfNeeded()})}},e.prototype.InitLinks=function(){var e=this,t=function(t){t.preventDefault();var o=t.currentTarget;e.$elModal&&e.$elModal.modal("hide"),$("body").removeClass("sm-nav-expanded"),e.DoHandleLink("","",o.href,o.target,!0===t.ctrlKey)};this.$elTopicContainer.on("click","a",t),$(".modal-body").on("click","a",t)},e.prototype.Init=function(){if(this.$elTopicContainer=$(this.options.elTopicContainer),!this.$elTopicContainer)throw new EInvalidHtmlElement("Invalid topic container element ["+this.options.elTopicContainer+"]")},e.prototype.Boot=function(){try{this.InitTrees(),this.InitLinks(),this.InitHistory(),this.InitToggler(),this.InitMask(),this.InitModal(),this.InitSearchEngine(),this.InitSearchForm(),this.InitHeadRoom(),this.InitSplitter(),this.InitResponsiveClasses(),this.doOnTopicChanged(),this.doProcessParameters()}catch(e){console.error("[HND-APP] An error occurred while booting the application =>",e.toString())}},e.prototype.OpenTreeToLevel=function(e,t){try{if(t){var o=$(e).jstree(!0);o&&$(o.get_json("#",{no_a_attr:!0,no_children:!1,no_data:!0,no_id:!1,no_li_attr:!0,no_state:!0,flat:!0})).each(function(e,n){var r=o.get_node($(this).attr("id"));r.parents.length<=t&&o.open_node(r)})}}catch(e){console.error("[HND-APP] An error occurred while opening the tree =>",e.toString())}},e.prototype.SelectTopicInToc=function(e,t,o){void 0===o&&(o=!1),"string"==typeof e&&""!==e||(e=$(this.options.elTopicContent).data("hnd-id")),"string"==typeof t&&""!==t||(t=$(this.options.elTopicContent).data("hnd-title")),"string"==typeof e&&""!==e&&(this.$elTreeContainers.jstree("deselect_all",!0),this.$elTreeContainers.jstree("select_node",e,!0,!1),t&&""!==t&&(document.title=t),o&&setTimeout(function(){var t=document.getElementById(e+"_anchor");t&&t.scrollIntoView()},this.options.animationDelay+50))},e}();e.App=n}(Hnd||(Hnd={})); \ No newline at end of file diff --git a/web/help/js/context/0.html b/web/help/js/context/0.html new file mode 100644 index 00000000..1cf3994a --- /dev/null +++ b/web/help/js/context/0.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Introduction" + + + + + + + + diff --git a/web/help/js/context/1.html b/web/help/js/context/1.html new file mode 100644 index 00000000..106e1e13 --- /dev/null +++ b/web/help/js/context/1.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "General" + + + + + + + + diff --git a/web/help/js/context/10.html b/web/help/js/context/10.html new file mode 100644 index 00000000..48e1a3f3 --- /dev/null +++ b/web/help/js/context/10.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Memory Watch" + + + + + + + + diff --git a/web/help/js/context/11.html b/web/help/js/context/11.html new file mode 100644 index 00000000..0bd437cd --- /dev/null +++ b/web/help/js/context/11.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua Scripting" + + + + + + + + diff --git a/web/help/js/context/12.html b/web/help/js/context/12.html new file mode 100644 index 00000000..126d706e --- /dev/null +++ b/web/help/js/context/12.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Getting Started" + + + + + + + + diff --git a/web/help/js/context/13.html b/web/help/js/context/13.html new file mode 100644 index 00000000..52c23404 --- /dev/null +++ b/web/help/js/context/13.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Auto Fire Settings" + + + + + + + + diff --git a/web/help/js/context/14.html b/web/help/js/context/14.html new file mode 100644 index 00000000..3df806a1 --- /dev/null +++ b/web/help/js/context/14.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Debugger" + + + + + + + + diff --git a/web/help/js/context/15.html b/web/help/js/context/15.html new file mode 100644 index 00000000..0229fade --- /dev/null +++ b/web/help/js/context/15.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Hex Editor" + + + + + + + + diff --git a/web/help/js/context/16.html b/web/help/js/context/16.html new file mode 100644 index 00000000..559c93d2 --- /dev/null +++ b/web/help/js/context/16.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "PPU Viewer" + + + + + + + + diff --git a/web/help/js/context/17.html b/web/help/js/context/17.html new file mode 100644 index 00000000..4cd92b40 --- /dev/null +++ b/web/help/js/context/17.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Name Table Viewer" + + + + + + + + diff --git a/web/help/js/context/18.html b/web/help/js/context/18.html new file mode 100644 index 00000000..1d9d12ec --- /dev/null +++ b/web/help/js/context/18.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "RAM Search" + + + + + + + + diff --git a/web/help/js/context/19.html b/web/help/js/context/19.html new file mode 100644 index 00000000..3aba801b --- /dev/null +++ b/web/help/js/context/19.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "FAQ / Guides" + + + + + + + + diff --git a/web/help/js/context/2.html b/web/help/js/context/2.html new file mode 100644 index 00000000..0476dba3 --- /dev/null +++ b/web/help/js/context/2.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Overview" + + + + + + + + diff --git a/web/help/js/context/20.html b/web/help/js/context/20.html new file mode 100644 index 00000000..8e6527bf --- /dev/null +++ b/web/help/js/context/20.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Tool Assisted Speedruns" + + + + + + + + diff --git a/web/help/js/context/21.html b/web/help/js/context/21.html new file mode 100644 index 00000000..80f9f390 --- /dev/null +++ b/web/help/js/context/21.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "ROM Hacking" + + + + + + + + diff --git a/web/help/js/context/22.html b/web/help/js/context/22.html new file mode 100644 index 00000000..23dc33d8 --- /dev/null +++ b/web/help/js/context/22.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.0" + + + + + + + + diff --git a/web/help/js/context/23.html b/web/help/js/context/23.html new file mode 100644 index 00000000..049fe6db --- /dev/null +++ b/web/help/js/context/23.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Technical Information" + + + + + + + + diff --git a/web/help/js/context/24.html b/web/help/js/context/24.html new file mode 100644 index 00000000..57968b5e --- /dev/null +++ b/web/help/js/context/24.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Movie & Savestate formats" + + + + + + + + diff --git a/web/help/js/context/25.html b/web/help/js/context/25.html new file mode 100644 index 00000000..3bc32fb8 --- /dev/null +++ b/web/help/js/context/25.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to ".fm2" + + + + + + + + diff --git a/web/help/js/context/26.html b/web/help/js/context/26.html new file mode 100644 index 00000000..1264910e --- /dev/null +++ b/web/help/js/context/26.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to ".fcm" + + + + + + + + diff --git a/web/help/js/context/27.html b/web/help/js/context/27.html new file mode 100644 index 00000000..133b973d --- /dev/null +++ b/web/help/js/context/27.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Savestate (.fcs)" + + + + + + + + diff --git a/web/help/js/context/28.html b/web/help/js/context/28.html new file mode 100644 index 00000000..a1b91d7c --- /dev/null +++ b/web/help/js/context/28.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Sound" + + + + + + + + diff --git a/web/help/js/context/29.html b/web/help/js/context/29.html new file mode 100644 index 00000000..d75682b8 --- /dev/null +++ b/web/help/js/context/29.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NSF Format" + + + + + + + + diff --git a/web/help/js/context/3.html b/web/help/js/context/3.html new file mode 100644 index 00000000..b3a39aa0 --- /dev/null +++ b/web/help/js/context/3.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "FCE Ultra Version History" + + + + + + + + diff --git a/web/help/js/context/30.html b/web/help/js/context/30.html new file mode 100644 index 00000000..df9766cf --- /dev/null +++ b/web/help/js/context/30.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Sound" + + + + + + + + diff --git a/web/help/js/context/31.html b/web/help/js/context/31.html new file mode 100644 index 00000000..645f7457 --- /dev/null +++ b/web/help/js/context/31.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Processing" + + + + + + + + diff --git a/web/help/js/context/32.html b/web/help/js/context/32.html new file mode 100644 index 00000000..1a1d74d8 --- /dev/null +++ b/web/help/js/context/32.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "CPU - 6502" + + + + + + + + diff --git a/web/help/js/context/33.html b/web/help/js/context/33.html new file mode 100644 index 00000000..ae6ca58a --- /dev/null +++ b/web/help/js/context/33.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "PPU - 2C02" + + + + + + + + diff --git a/web/help/js/context/34.html b/web/help/js/context/34.html new file mode 100644 index 00000000..b434083a --- /dev/null +++ b/web/help/js/context/34.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Scrolling 1" + + + + + + + + diff --git a/web/help/js/context/35.html b/web/help/js/context/35.html new file mode 100644 index 00000000..69f17194 --- /dev/null +++ b/web/help/js/context/35.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Scrolling 2" + + + + + + + + diff --git a/web/help/js/context/36.html b/web/help/js/context/36.html new file mode 100644 index 00000000..f1a7ce19 --- /dev/null +++ b/web/help/js/context/36.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES RAM (Mapping/Finding Values)" + + + + + + + + diff --git a/web/help/js/context/37.html b/web/help/js/context/37.html new file mode 100644 index 00000000..6e52beb0 --- /dev/null +++ b/web/help/js/context/37.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Debug" + + + + + + + + diff --git a/web/help/js/context/38.html b/web/help/js/context/38.html new file mode 100644 index 00000000..7cfe9b76 --- /dev/null +++ b/web/help/js/context/38.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Trace Logger" + + + + + + + + diff --git a/web/help/js/context/39.html b/web/help/js/context/39.html new file mode 100644 index 00000000..67833dbb --- /dev/null +++ b/web/help/js/context/39.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Code/Data Logger" + + + + + + + + diff --git a/web/help/js/context/4.html b/web/help/js/context/4.html new file mode 100644 index 00000000..35fbfde2 --- /dev/null +++ b/web/help/js/context/4.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Getting Started" + + + + + + + + diff --git a/web/help/js/context/40.html b/web/help/js/context/40.html new file mode 100644 index 00000000..5667ae51 --- /dev/null +++ b/web/help/js/context/40.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Game Genie Encoder/Decoder" + + + + + + + + diff --git a/web/help/js/context/41.html b/web/help/js/context/41.html new file mode 100644 index 00000000..44face0b --- /dev/null +++ b/web/help/js/context/41.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Config" + + + + + + + + diff --git a/web/help/js/context/42.html b/web/help/js/context/42.html new file mode 100644 index 00000000..21df67a0 --- /dev/null +++ b/web/help/js/context/42.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Input" + + + + + + + + diff --git a/web/help/js/context/43.html b/web/help/js/context/43.html new file mode 100644 index 00000000..dec41dfa --- /dev/null +++ b/web/help/js/context/43.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Directories" + + + + + + + + diff --git a/web/help/js/context/44.html b/web/help/js/context/44.html new file mode 100644 index 00000000..6df1f15c --- /dev/null +++ b/web/help/js/context/44.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Sound" + + + + + + + + diff --git a/web/help/js/context/45.html b/web/help/js/context/45.html new file mode 100644 index 00000000..7cc12aa3 --- /dev/null +++ b/web/help/js/context/45.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Video" + + + + + + + + diff --git a/web/help/js/context/46.html b/web/help/js/context/46.html new file mode 100644 index 00000000..baac4b3b --- /dev/null +++ b/web/help/js/context/46.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Map Hotkeys" + + + + + + + + diff --git a/web/help/js/context/47.html b/web/help/js/context/47.html new file mode 100644 index 00000000..ebd4ad7e --- /dev/null +++ b/web/help/js/context/47.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.3 (changelog)" + + + + + + + + diff --git a/web/help/js/context/48.html b/web/help/js/context/48.html new file mode 100644 index 00000000..36c99d3f --- /dev/null +++ b/web/help/js/context/48.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.1 (changelog)" + + + + + + + + diff --git a/web/help/js/context/49.html b/web/help/js/context/49.html new file mode 100644 index 00000000..af67d469 --- /dev/null +++ b/web/help/js/context/49.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "TAS Editor" + + + + + + + + diff --git a/web/help/js/context/5.html b/web/help/js/context/5.html new file mode 100644 index 00000000..652c6cda --- /dev/null +++ b/web/help/js/context/5.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Movie Recording" + + + + + + + + diff --git a/web/help/js/context/50.html b/web/help/js/context/50.html new file mode 100644 index 00000000..29ea43ab --- /dev/null +++ b/web/help/js/context/50.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Command Line Options" + + + + + + + + diff --git a/web/help/js/context/51.html b/web/help/js/context/51.html new file mode 100644 index 00000000..c89abb09 --- /dev/null +++ b/web/help/js/context/51.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Menu Items & Submenus" + + + + + + + + diff --git a/web/help/js/context/52.html b/web/help/js/context/52.html new file mode 100644 index 00000000..a96e0d9b --- /dev/null +++ b/web/help/js/context/52.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Timing" + + + + + + + + diff --git a/web/help/js/context/53.html b/web/help/js/context/53.html new file mode 100644 index 00000000..39881f50 --- /dev/null +++ b/web/help/js/context/53.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "GUI" + + + + + + + + diff --git a/web/help/js/context/54.html b/web/help/js/context/54.html new file mode 100644 index 00000000..2239f70f --- /dev/null +++ b/web/help/js/context/54.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Palette" + + + + + + + + diff --git a/web/help/js/context/55.html b/web/help/js/context/55.html new file mode 100644 index 00000000..48f78207 --- /dev/null +++ b/web/help/js/context/55.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Network Play" + + + + + + + + diff --git a/web/help/js/context/56.html b/web/help/js/context/56.html new file mode 100644 index 00000000..5beef1a4 --- /dev/null +++ b/web/help/js/context/56.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "NES Menu" + + + + + + + + diff --git a/web/help/js/context/57.html b/web/help/js/context/57.html new file mode 100644 index 00000000..afb031e7 --- /dev/null +++ b/web/help/js/context/57.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Game file compatibility" + + + + + + + + diff --git a/web/help/js/context/58.html b/web/help/js/context/58.html new file mode 100644 index 00000000..879f638c --- /dev/null +++ b/web/help/js/context/58.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Convert fcm" + + + + + + + + diff --git a/web/help/js/context/59.html b/web/help/js/context/59.html new file mode 100644 index 00000000..8a766088 --- /dev/null +++ b/web/help/js/context/59.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Introduction" + + + + + + + + diff --git a/web/help/js/context/6.html b/web/help/js/context/6.html new file mode 100644 index 00000000..5042dfdb --- /dev/null +++ b/web/help/js/context/6.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "AVI Capturing" + + + + + + + + diff --git a/web/help/js/context/60.html b/web/help/js/context/60.html new file mode 100644 index 00000000..70c9acde --- /dev/null +++ b/web/help/js/context/60.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Text Hooker" + + + + + + + + diff --git a/web/help/js/context/61.html b/web/help/js/context/61.html new file mode 100644 index 00000000..7c719d72 --- /dev/null +++ b/web/help/js/context/61.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Using Lua" + + + + + + + + diff --git a/web/help/js/context/62.html b/web/help/js/context/62.html new file mode 100644 index 00000000..86675349 --- /dev/null +++ b/web/help/js/context/62.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.2 (changelog)" + + + + + + + + diff --git a/web/help/js/context/63.html b/web/help/js/context/63.html new file mode 100644 index 00000000..4dd937d8 --- /dev/null +++ b/web/help/js/context/63.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua Bot" + + + + + + + + diff --git a/web/help/js/context/64.html b/web/help/js/context/64.html new file mode 100644 index 00000000..714adbc9 --- /dev/null +++ b/web/help/js/context/64.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua Functions List" + + + + + + + + diff --git a/web/help/js/context/65.html b/web/help/js/context/65.html new file mode 100644 index 00000000..0a79096f --- /dev/null +++ b/web/help/js/context/65.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.0.3 (changelog)" + + + + + + + + diff --git a/web/help/js/context/66.html b/web/help/js/context/66.html new file mode 100644 index 00000000..e599d0f3 --- /dev/null +++ b/web/help/js/context/66.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Movie Options" + + + + + + + + diff --git a/web/help/js/context/67.html b/web/help/js/context/67.html new file mode 100644 index 00000000..6bf94af1 --- /dev/null +++ b/web/help/js/context/67.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1 (changelog)" + + + + + + + + diff --git a/web/help/js/context/68.html b/web/help/js/context/68.html new file mode 100644 index 00000000..45636678 --- /dev/null +++ b/web/help/js/context/68.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Context Menu Items" + + + + + + + + diff --git a/web/help/js/context/69.html b/web/help/js/context/69.html new file mode 100644 index 00000000..98f80186 --- /dev/null +++ b/web/help/js/context/69.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Palette Options" + + + + + + + + diff --git a/web/help/js/context/7.html b/web/help/js/context/7.html new file mode 100644 index 00000000..da983b3c --- /dev/null +++ b/web/help/js/context/7.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Famicom Disk Sytem" + + + + + + + + diff --git a/web/help/js/context/70.html b/web/help/js/context/70.html new file mode 100644 index 00000000..41659069 --- /dev/null +++ b/web/help/js/context/70.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Troubleshooting" + + + + + + + + diff --git a/web/help/js/context/71.html b/web/help/js/context/71.html new file mode 100644 index 00000000..2d181ff1 --- /dev/null +++ b/web/help/js/context/71.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Customizing through the Config File" + + + + + + + + diff --git a/web/help/js/context/72.html b/web/help/js/context/72.html new file mode 100644 index 00000000..dc09d615 --- /dev/null +++ b/web/help/js/context/72.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.1 (changelog)" + + + + + + + + diff --git a/web/help/js/context/73.html b/web/help/js/context/73.html new file mode 100644 index 00000000..ed12bbee --- /dev/null +++ b/web/help/js/context/73.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.2 (changelog)" + + + + + + + + diff --git a/web/help/js/context/74.html b/web/help/js/context/74.html new file mode 100644 index 00000000..1fc11711 --- /dev/null +++ b/web/help/js/context/74.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "RAM Watch" + + + + + + + + diff --git a/web/help/js/context/75.html b/web/help/js/context/75.html new file mode 100644 index 00000000..e38276c3 --- /dev/null +++ b/web/help/js/context/75.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.3 (changelog)" + + + + + + + + diff --git a/web/help/js/context/76.html b/web/help/js/context/76.html new file mode 100644 index 00000000..b7237cca --- /dev/null +++ b/web/help/js/context/76.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.1 (changelog)" + + + + + + + + diff --git a/web/help/js/context/77.html b/web/help/js/context/77.html new file mode 100644 index 00000000..e0613194 --- /dev/null +++ b/web/help/js/context/77.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.4 (changelog)" + + + + + + + + diff --git a/web/help/js/context/78.html b/web/help/js/context/78.html new file mode 100644 index 00000000..674eb65e --- /dev/null +++ b/web/help/js/context/78.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.1.5 (changelog)" + + + + + + + + diff --git a/web/help/js/context/79.html b/web/help/js/context/79.html new file mode 100644 index 00000000..165278d5 --- /dev/null +++ b/web/help/js/context/79.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Overview of Included Scripts" + + + + + + + + diff --git a/web/help/js/context/8.html b/web/help/js/context/8.html new file mode 100644 index 00000000..e21a82f0 --- /dev/null +++ b/web/help/js/context/8.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Tools" + + + + + + + + diff --git a/web/help/js/context/80.html b/web/help/js/context/80.html new file mode 100644 index 00000000..0d7a8674 --- /dev/null +++ b/web/help/js/context/80.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.0 (changelog)" + + + + + + + + diff --git a/web/help/js/context/81.html b/web/help/js/context/81.html new file mode 100644 index 00000000..0905e6e5 --- /dev/null +++ b/web/help/js/context/81.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "LuaPerks" + + + + + + + + diff --git a/web/help/js/context/82.html b/web/help/js/context/82.html new file mode 100644 index 00000000..4d67f7ba --- /dev/null +++ b/web/help/js/context/82.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.2.2 (changelog)" + + + + + + + + diff --git a/web/help/js/context/83.html b/web/help/js/context/83.html new file mode 100644 index 00000000..7bf5b51c --- /dev/null +++ b/web/help/js/context/83.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to ".nl files format" + + + + + + + + diff --git a/web/help/js/context/84.html b/web/help/js/context/84.html new file mode 100644 index 00000000..dcf75712 --- /dev/null +++ b/web/help/js/context/84.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "What's New? 2.3.0 (changelog)" + + + + + + + + diff --git a/web/help/js/context/9.html b/web/help/js/context/9.html new file mode 100644 index 00000000..bec6086c --- /dev/null +++ b/web/help/js/context/9.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Cheat Search" + + + + + + + + diff --git a/web/help/js/hnd.js b/web/help/js/hnd.js deleted file mode 100644 index 7c3b9e4d..00000000 --- a/web/help/js/hnd.js +++ /dev/null @@ -1 +0,0 @@ -jQuery.fn.highlight=function(a){function d(b,a){var e=0;if(b.nodeType==3){var c=b.data.toUpperCase().indexOf(a);if(c>=0){e=document.createElement("span");e.className="highlight";c=b.splitText(c);c.splitText(a.length);var g=c.cloneNode(!0);e.appendChild(g);c.parentNode.replaceChild(e,c);e=1}}else if(b.nodeType==1&&b.childNodes&&!/(script|style)/i.test(b.tagName))for(c=0;c=0;c--)b=$.inArray(a[c][0],this.aResults),b>=0&&this.aResults.splice(b,1)},IntersectResultTopics:function(a){if(a&& a.length)for(var b=!1,c=this.aResults.length-1;c>=0;c--){for(var b=!1,d=0;d-1?o.scores[i][Score.TopicScore]=o.scores[i][Score.TopicScore]+t:o.scores.push([e,t])})},r.prototype.Clear=function(){this.scores=[]},r.prototype.ExcludeTopics=function(r){var o=this;if(!r||!r.forEach)return void console.error("Invalid ExcludeTopics call");r.forEach(function(r){if(!r||!Array.isArray(r)||2!==r.length)return void console.error("Invalid data in ExcludeTopics");var e=r[Score.TopicNumber];if("number"!=typeof e||e<0)return void console.error("Invalid topic data in ExcludeTopics");var t=o.FindTopicIndex(e);t>-1&&o.scores.splice(t,1)})},r.prototype.SortByScore=function(){this.scores.sort(function(r,o){return r[Score.TopicScore]>o[Score.TopicScore]?-1:r[Score.TopicScore]0&&'"'===t[0];)t=t.substr(1);for(;t.length>0&&'"'===t[t.length-1];)t=t.substr(0,t.length-1);switch(i){case"-":this.inputWordsExcluded.AddWord(t);break;case"+":this.inputWordsIncluded.AddWord(t);break;default:this.inputWordsMandatory.AddWord(t)}}}},r.prototype.PerformSearch=function(r){var o=this;if(this.resultScoreIncluded=new HndJsSeResultScore,this.resultScoreMandatory=new HndJsSeResultScore,this.resultScoreExcluded=new HndJsSeResultScore,!r||!r.length)return console.error("Invalid word list data"),[];var e;r.forEach(function(r){if("string"==typeof r)e=r.trim().toLowerCase();else{if(!Array.isArray(r))return void console.error("Invalid element in word list data:",r);if(""==e)return void console.warn("Empty word should not be included in list");-1!==o.inputWordsIncluded.FindPartial(e)&&o.resultScoreIncluded.AddTopics(r),-1!==o.inputWordsMandatory.FindPartial(e)&&o.resultScoreMandatory.AddTopics(r),-1!==o.inputWordsExcluded.FindPartial(e)&&o.resultScoreExcluded.AddTopics(r)}});var t=this.resultScoreIncluded;return t.AddTopics(this.resultScoreMandatory.scores),t.ExcludeTopics(this.resultScoreExcluded.scores),t.SortByScore(),t.scores},r}(); \ No newline at end of file diff --git a/web/help/js/jquery-ui-1.8.12.custom.min.js b/web/help/js/jquery-ui-1.8.12.custom.min.js deleted file mode 100644 index 0d9dbd68..00000000 --- a/web/help/js/jquery-ui-1.8.12.custom.min.js +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * jQuery UI 1.8.12 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.12",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106, -NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this, -"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position"); -if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f, -"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h, -d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}}); -c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& -e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= -d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| -(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); -this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= -this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); -if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); -this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ -g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", -function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; -this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= --1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; -d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= -d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, -e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); -j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); -if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, -this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, -load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, -"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, -url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.12"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);/* - * jQuery UI Draggable 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Draggables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.lefth[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.toph[3]?j-this.offset.click.toph[2]?k-this.offset.click.left=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f=k&&g<=l||h>=k&&h<=l||gl)&&(e>=i&&e<=j||f>=i&&f<=j||ej);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),a.browser.opera&&/relative/.test(f.css("position"))&&f.css({position:"relative",top:"auto",left:"auto"}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),ea.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.17"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10),position:b.css("position")})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,e){a(b).each(function(){var b=a(this),f=a(this).data("resizable-alsoresize"),g={},i=e&&e.length?e:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(i,function(a,b){var c=(f[b]||0)+(h[b]||0);c&&c>=0&&(g[b]=c||null)}),a.browser.opera&&/relative/.test(b.css("position"))&&(d._revertToRelativePosition=!0,b.css({position:"absolute",top:"auto",left:"auto"})),b.css(g)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};d._revertToRelativePosition&&(d._revertToRelativePosition=!1,typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)),a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);/* - * jQuery UI Selectable 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.righth||i.bottome&&i.rightf&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+jf&&b+ka[this.floating?"width":"height"]?l:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.topthis.containment[3]?h-this.offset.click.topthis.containment[2]?i-this.offset.click.left=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash){e.selected=a;return!1}}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1){this.blur();return!1}e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected")){e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur();return!1}if(!f.length){e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur();return!1}}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$="+a+"]")));return a},destroy:function(){var b=this.options;this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie);return this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0]));return this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a])));return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup();return this},url:function(a,b){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.17"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a1){res+=cache.tagConnector;}}else if(this.hasChildren()!==false){res+=cache.tagExpander;}else{res+=cache.tagConnector;} -if(opts.checkbox&&data.hideCheckbox!==true&&!data.isStatusNode){res+=cache.tagCheckbox;} -if(data.icon){res+="";}else if(data.icon===false){noop();}else{res+=cache.tagNodeIcon;} -var nodeTitle="";if(opts.onCustomRender){nodeTitle=opts.onCustomRender.call(tree,this)||"";} -if(!nodeTitle){var tooltip=data.tooltip?' title="'+data.tooltip.replace(/\"/g,'"')+'"':'',href=data.href||"#";if(opts.noLink||data.noLink){nodeTitle=''+data.title+'';}else{nodeTitle=''+data.title+'';}} -res+=nodeTitle;return res;},_fixOrder:function(){var cl=this.childList;if(!cl||!this.ul){return;} -var childLI=this.ul.firstChild;for(var i=0,l=cl.length-1;i1){this.ul.className=cn.container+" "+cn.noConnector;}else{this.ul.className=cn.container;}}else if(parent){if(!this.li){firstTime=true;this.li=document.createElement("li");this.li.dtnode=this;if(data.key&&opts.generateIds){this.li.id=opts.idPrefix+data.key;} -this.span=document.createElement("span");this.span.className=cn.title;this.li.appendChild(this.span);if(!parent.ul){parent.ul=document.createElement("ul");parent.ul.style.display="none";parent.li.appendChild(parent.ul);} -parent.ul.appendChild(this.li);} -this.span.innerHTML=this._getInnerHtml();var cnList=[];cnList.push(cn.node);if(data.isFolder){cnList.push(cn.folder);} -if(this.bExpanded){cnList.push(cn.expanded);} -if(this.hasChildren()!==false){cnList.push(cn.hasChildren);} -if(data.isLazy&&this.childList===null){cnList.push(cn.lazy);} -if(isLastSib){cnList.push(cn.lastsib);} -if(this.bSelected){cnList.push(cn.selected);} -if(this.hasSubSel){cnList.push(cn.partsel);} -if(tree.activeNode===this){cnList.push(cn.active);} -if(data.addClass){cnList.push(data.addClass);} -cnList.push(cn.combinedExpanderPrefix -+(this.bExpanded?"e":"c") -+(data.isLazy&&this.childList===null?"d":"") -+(isLastSib?"l":""));cnList.push(cn.combinedIconPrefix -+(this.bExpanded?"e":"c") -+(data.isFolder?"f":""));this.span.className=cnList.join(" ");this.li.className=isLastSib?cn.lastsib:"";if(firstTime&&opts.onCreate){opts.onCreate.call(tree,this,this.span);} -if(opts.onRender){opts.onRender.call(tree,this,this.span);}} -if((this.bExpanded||includeInvisible===true)&&this.childList){for(var i=0,l=this.childList.length;iy?1:-1;};cl.sort(cmp);if(deep){for(var i=0,l=cl.length;i0){this.childList[0].focus();}else{this.focus();}} -break;case DTNodeStatus_Loading:this._isLoading=true;$(this.span).addClass(this.tree.options.classNames.nodeLoading);if(!this.parent){this._setStatusNode({title:this.tree.options.strings.loading+info,tooltip:tooltip,addClass:this.tree.options.classNames.nodeWait});} -break;case DTNodeStatus_Error:this._isLoading=false;this._setStatusNode({title:this.tree.options.strings.loadError+info,tooltip:tooltip,addClass:this.tree.options.classNames.nodeError});break;default:throw"Bad LazyNodeStatus: '"+lts+"'.";}},_parentList:function(includeRoot,includeSelf){var l=[];var dtn=includeSelf?this:this.parent;while(dtn){if(includeRoot||dtn.parent){l.unshift(dtn);} -dtn=dtn.parent;} -return l;},getLevel:function(){var level=0;var dtn=this.parent;while(dtn){level++;dtn=dtn.parent;} -return level;},_getTypeForOuterNodeEvent:function(event){var cns=this.tree.options.classNames;var target=event.target;if(target.className.indexOf(cns.node)<0){return null;} -var eventX=event.pageX-target.offsetLeft;var eventY=event.pageY-target.offsetTop;for(var i=0,l=target.childNodes.length;i=x&&eventX<=(x+nx)&&eventY>=y&&eventY<=(y+ny)){if(cn.className==cns.title){return"title";}else if(cn.className==cns.expander){return"expander";}else if(cn.className==cns.checkbox){return"checkbox";}else if(cn.className==cns.nodeIcon){return"icon";}}} -return"prefix";},getEventTargetType:function(event){var tcn=event&&event.target?event.target.className:"",cns=this.tree.options.classNames;if(tcn===cns.title){return"title";}else if(tcn===cns.expander){return"expander";}else if(tcn===cns.checkbox){return"checkbox";}else if(tcn===cns.nodeIcon){return"icon";}else if(tcn===cns.empty||tcn===cns.vline||tcn===cns.connector){return"prefix";}else if(tcn.indexOf(cns.node)>=0){return this._getTypeForOuterNodeEvent(event);} -return null;},isVisible:function(){var parents=this._parentList(true,false);for(var i=0,l=parents.length;ia").focus();}catch(e){}},isFocused:function(){return(this.tree.tnFocused===this);},_activate:function(flag,fireEvents){this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o",flag,fireEvents,this);var opts=this.tree.options;if(this.data.isStatusNode){return;} -if(fireEvents&&opts.onQueryActivate&&opts.onQueryActivate.call(this.tree,flag,this)===false){return;} -if(flag){if(this.tree.activeNode){if(this.tree.activeNode===this){return;} -this.tree.activeNode.deactivate();} -if(opts.activeVisible){this.makeVisible();} -this.tree.activeNode=this;if(opts.persist){$.cookie(opts.cookieId+"-active",this.data.key,opts.cookie);} -this.tree.persistence.activeKey=this.data.key;$(this.span).addClass(opts.classNames.active);if(fireEvents&&opts.onActivate){opts.onActivate.call(this.tree,this);}}else{if(this.tree.activeNode===this){if(opts.onQueryActivate&&opts.onQueryActivate.call(this.tree,false,this)===false){return;} -$(this.span).removeClass(opts.classNames.active);if(opts.persist){$.cookie(opts.cookieId+"-active","",opts.cookie);} -this.tree.persistence.activeKey=null;this.tree.activeNode=null;if(fireEvents&&opts.onDeactivate){opts.onDeactivate.call(this.tree,this);}}}},activate:function(){this._activate(true,true);},activateSilently:function(){this._activate(true,false);},deactivate:function(){this._activate(false,true);},isActive:function(){return(this.tree.activeNode===this);},_userActivate:function(){var activate=true;var expand=false;if(this.data.isFolder){switch(this.tree.options.clickFolderMode){case 2:activate=false;expand=true;break;case 3:activate=expand=true;break;}} -if(this.parent===null){expand=false;} -if(expand){this.toggleExpand();this.focus();} -if(activate){this.activate();}},_setSubSel:function(hasSubSel){if(hasSubSel){this.hasSubSel=true;$(this.span).addClass(this.tree.options.classNames.partsel);}else{this.hasSubSel=false;$(this.span).removeClass(this.tree.options.classNames.partsel);}},_updatePartSelectionState:function(){var sel;if(!this.hasChildren()){sel=(this.bSelected&&!this.data.unselectable&&!this.data.isStatusNode);this._setSubSel(false);return sel;} -var i,l,cl=this.childList,allSelected=true,allDeselected=true;for(i=0,l=cl.length;i=0;i--){sib=parents[i].getNextSibling();if(sib){break;}}} -if(sib){sib.focus();} -break;default:handled=false;} -if(handled){event.preventDefault();}},_onKeypress:function(event){},_onFocus:function(event){var opts=this.tree.options;if(event.type=="blur"||event.type=="focusout"){if(opts.onBlur){opts.onBlur.call(this.tree,this);} -if(this.tree.tnFocused){$(this.tree.tnFocused.span).removeClass(opts.classNames.focused);} -this.tree.tnFocused=null;if(opts.persist){$.cookie(opts.cookieId+"-focus","",opts.cookie);}}else if(event.type=="focus"||event.type=="focusin"){if(this.tree.tnFocused&&this.tree.tnFocused!==this){this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o",this.tree.tnFocused);$(this.tree.tnFocused.span).removeClass(opts.classNames.focused);} -this.tree.tnFocused=this;if(opts.onFocus){opts.onFocus.call(this.tree,this);} -$(this.tree.tnFocused.span).addClass(opts.classNames.focused);if(opts.persist){$.cookie(opts.cookieId+"-focus",this.data.key,opts.cookie);}}},visit:function(fn,includeSelf){var res=true;if(includeSelf===true){res=fn(this);if(res===false||res=="skip"){return res;}} -if(this.childList){for(var i=0,l=this.childList.length;i reloading %s...",this,keyPath,child);var self=this;child.reloadChildren(function(node,isOk){if(isOk){tree.logDebug("%s._loadKeyPath(%s) -> reloaded %s.",node,keyPath,node);callback.call(tree,child,"loaded");node._loadKeyPath(segList.join(tree.options.keyPathSeparator),callback);}else{tree.logWarning("%s._loadKeyPath(%s) -> reloadChildren() failed.",self,keyPath);callback.call(tree,child,"error");}});}else{callback.call(tree,child,"loaded");child._loadKeyPath(segList.join(tree.options.keyPathSeparator),callback);} -return;}} -tree.logWarning("Node not found: "+seg);return;},resetLazy:function(){if(this.parent===null){throw"Use tree.reload() instead";}else if(!this.data.isLazy){throw"node.resetLazy() requires lazy nodes.";} -this.expand(false);this.removeChildren();},_addChildNode:function(dtnode,beforeNode){var tree=this.tree,opts=tree.options,pers=tree.persistence;dtnode.parent=this;if(this.childList===null){this.childList=[];}else if(!beforeNode){if(this.childList.length>0){$(this.childList[this.childList.length-1].span).removeClass(opts.classNames.lastsib);}} -if(beforeNode){var iBefore=$.inArray(beforeNode,this.childList);if(iBefore<0){throw" must be a child of ";} -this.childList.splice(iBefore,0,dtnode);}else{this.childList.push(dtnode);} -var isInitializing=tree.isInitializing();if(opts.persist&&pers.cookiesFound&&isInitializing){if(pers.activeKey===dtnode.data.key){tree.activeNode=dtnode;} -if(pers.focusedKey===dtnode.data.key){tree.focusNode=dtnode;} -dtnode.bExpanded=($.inArray(dtnode.data.key,pers.expandedKeyList)>=0);dtnode.bSelected=($.inArray(dtnode.data.key,pers.selectedKeyList)>=0);}else{if(dtnode.data.activate){tree.activeNode=dtnode;if(opts.persist){pers.activeKey=dtnode.data.key;}} -if(dtnode.data.focus){tree.focusNode=dtnode;if(opts.persist){pers.focusedKey=dtnode.data.key;}} -dtnode.bExpanded=(dtnode.data.expand===true);if(dtnode.bExpanded&&opts.persist){pers.addExpand(dtnode.data.key);} -dtnode.bSelected=(dtnode.data.select===true);if(dtnode.bSelected&&opts.persist){pers.addSelect(dtnode.data.key);}} -if(opts.minExpandLevel>=dtnode.getLevel()){this.bExpanded=true;} -if(dtnode.bSelected&&opts.selectMode==3){var p=this;while(p){if(!p.hasSubSel){p._setSubSel(true);} -p=p.parent;}} -if(tree.bEnableUpdate){this.render();} -return dtnode;},addChild:function(obj,beforeNode){if(typeof(obj)=="string"){throw"Invalid data type for "+obj;}else if(!obj||obj.length===0){return;}else if(obj instanceof DynaTreeNode){return this._addChildNode(obj,beforeNode);} -if(!obj.length){obj=[obj];} -var prevFlag=this.tree.enableUpdate(false);var tnFirst=null;for(var i=0,l=obj.length;i=0){this.expandedKeyList.splice(idx,1);$.cookie(this.cookieId+"-expand",this.expandedKeyList.join(","),this.cookieOpts);}},addSelect:function(key){if($.inArray(key,this.selectedKeyList)<0){this.selectedKeyList.push(key);$.cookie(this.cookieId+"-select",this.selectedKeyList.join(","),this.cookieOpts);}},clearSelect:function(key){var idx=$.inArray(key,this.selectedKeyList);if(idx>=0){this.selectedKeyList.splice(idx,1);$.cookie(this.cookieId+"-select",this.selectedKeyList.join(","),this.cookieOpts);}},isReloading:function(){return this.cookiesFound===true;},toDict:function(){return{cookiesFound:this.cookiesFound,activeKey:this.activeKey,focusedKey:this.activeKey,expandedKeyList:this.expandedKeyList,selectedKeyList:this.selectedKeyList};},lastentry:undefined};var DynaTree=Class.create();DynaTree.version="$Version: 1.2.1_rc3$";DynaTree.prototype={initialize:function($widget){this.phase="init";this.$widget=$widget;this.options=$widget.options;this.$tree=$widget.element;this.timer=null;this.divTree=this.$tree.get(0);_initDragAndDrop(this);},_load:function(callback){var $widget=this.$widget;var opts=this.options,self=this;this.bEnableUpdate=true;this._nodeCount=1;this.activeNode=null;this.focusNode=null;if(opts.rootVisible!==undefined){this.logWarning("Option 'rootVisible' is no longer supported.");} -if(opts.minExpandLevel<1){this.logWarning("Option 'minExpandLevel' must be >= 1.");opts.minExpandLevel=1;} -if(opts.classNames!==$.ui.dynatree.prototype.options.classNames){opts.classNames=$.extend({},$.ui.dynatree.prototype.options.classNames,opts.classNames);} -if(opts.ajaxDefaults!==$.ui.dynatree.prototype.options.ajaxDefaults){opts.ajaxDefaults=$.extend({},$.ui.dynatree.prototype.options.ajaxDefaults,opts.ajaxDefaults);} -if(opts.dnd!==$.ui.dynatree.prototype.options.dnd){opts.dnd=$.extend({},$.ui.dynatree.prototype.options.dnd,opts.dnd);} -if(!opts.imagePath){$("script").each(function(){var _rexDtLibName=/.*dynatree[^\/]*\.js$/i;if(this.src.search(_rexDtLibName)>=0){if(this.src.indexOf("/")>=0){opts.imagePath=this.src.slice(0,this.src.lastIndexOf("/"))+"/skin/";}else{opts.imagePath="skin/";} -self.logDebug("Guessing imagePath from '%s': '%s'",this.src,opts.imagePath);return false;}});} -this.persistence=new DynaTreeStatus(opts.cookieId,opts.cookie);if(opts.persist){if(!$.cookie){_log("warn","Please include jquery.cookie.js to use persistence.");} -this.persistence.read();} -this.logDebug("DynaTree.persistence: %o",this.persistence.toDict());this.cache={tagEmpty:"",tagVline:"",tagExpander:"",tagConnector:"",tagNodeIcon:"",tagCheckbox:"",lastentry:undefined};if(opts.children||(opts.initAjax&&opts.initAjax.url)||opts.initId){$(this.divTree).empty();} -var $ulInitialize=this.$tree.find(">ul:first").hide();this.tnRoot=new DynaTreeNode(null,this,{});this.tnRoot.bExpanded=true;this.tnRoot.render();this.divTree.appendChild(this.tnRoot.ul);var root=this.tnRoot;var isReloading=(opts.persist&&this.persistence.isReloading());var isLazy=false;var prevFlag=this.enableUpdate(false);this.logDebug("Dynatree._load(): read tree structure...");if(opts.children){root.addChild(opts.children);}else if(opts.initAjax&&opts.initAjax.url){isLazy=true;root.data.isLazy=true;this._reloadAjax(callback);}else if(opts.initId){this._createFromTag(root,$("#"+opts.initId));}else{this._createFromTag(root,$ulInitialize);$ulInitialize.remove();} -this._checkConsistency();if(!isLazy&&opts.selectMode==3){root._updatePartSelectionState();} -this.logDebug("Dynatree._load(): render nodes...");this.enableUpdate(prevFlag);this.logDebug("Dynatree._load(): bind events...");this.$widget.bind();this.logDebug("Dynatree._load(): postInit...");this.phase="postInit";if(opts.persist){this.persistence.write();} -if(this.focusNode&&this.focusNode.isVisible()){this.logDebug("Focus on init: %o",this.focusNode);this.focusNode.focus();} -if(!isLazy){if(opts.onPostInit){opts.onPostInit.call(this,isReloading,false);} -if(callback){callback.call(this,"ok");}} -this.phase="idle";},_reloadAjax:function(callback){var opts=this.options;if(!opts.initAjax||!opts.initAjax.url){throw"tree.reload() requires 'initAjax' mode.";} -var pers=this.persistence;var ajaxOpts=$.extend({},opts.initAjax);if(ajaxOpts.addActiveKey){ajaxOpts.data.activeKey=pers.activeKey;} -if(ajaxOpts.addFocusedKey){ajaxOpts.data.focusedKey=pers.focusedKey;} -if(ajaxOpts.addExpandedKeyList){ajaxOpts.data.expandedKeyList=pers.expandedKeyList.join(",");} -if(ajaxOpts.addSelectedKeyList){ajaxOpts.data.selectedKeyList=pers.selectedKeyList.join(",");} -if(ajaxOpts.success){this.logWarning("initAjax: success callback is ignored; use onPostInit instead.");} -if(ajaxOpts.error){this.logWarning("initAjax: error callback is ignored; use onPostInit instead.");} -var isReloading=pers.isReloading();ajaxOpts.success=function(dtnode,data,textStatus){if(opts.selectMode==3){dtnode.tree.tnRoot._updatePartSelectionState();} -if(opts.onPostInit){opts.onPostInit.call(dtnode.tree,isReloading,false);} -if(callback){callback.call(dtnode.tree,"ok");}};ajaxOpts.error=function(dtnode,XMLHttpRequest,textStatus,errorThrown){if(opts.onPostInit){opts.onPostInit.call(dtnode.tree,isReloading,true,XMLHttpRequest,textStatus,errorThrown);} -if(callback){callback.call(dtnode.tree,"error",XMLHttpRequest,textStatus,errorThrown);}};this.logDebug("Dynatree._init(): send Ajax request...");this.tnRoot.appendAjax(ajaxOpts);},toString:function(){return"Dynatree '"+this.$tree.attr("id")+"'";},toDict:function(){return this.tnRoot.toDict(true);},serializeArray:function(stopOnParents){var nodeList=this.getSelectedNodes(stopOnParents),name=this.$tree.attr("name")||this.$tree.attr("id"),arr=[];for(var i=0,l=nodeList.length;i=2){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments);}},logInfo:function(msg){if(this.options.debugLevel>=1){Array.prototype.unshift.apply(arguments,["info"]);_log.apply(this,arguments);}},logWarning:function(msg){Array.prototype.unshift.apply(arguments,["warn"]);_log.apply(this,arguments);},isInitializing:function(){return(this.phase=="init"||this.phase=="postInit");},isReloading:function(){return(this.phase=="init"||this.phase=="postInit")&&this.options.persist&&this.persistence.cookiesFound;},isUserEvent:function(){return(this.phase=="userEvent");},redraw:function(){this.tnRoot.render(false,false);},renderInvisibleNodes:function(){this.tnRoot.render(false,true);},reload:function(callback){this._load(callback);},getRoot:function(){return this.tnRoot;},enable:function(){this.$widget.enable();},disable:function(){this.$widget.disable();},getNodeByKey:function(key){var el=document.getElementById(this.options.idPrefix+key);if(el){return el.dtnode?el.dtnode:null;} -var match=null;this.visit(function(node){if(node.data.key==key){match=node;return false;}},true);return match;},getActiveNode:function(){return this.activeNode;},reactivate:function(setFocus){var node=this.activeNode;if(node){this.activeNode=null;node.activate();if(setFocus){node.focus();}}},getSelectedNodes:function(stopOnParents){var nodeList=[];this.tnRoot.visit(function(node){if(node.bSelected){nodeList.push(node);if(stopOnParents===true){return"skip";}}});return nodeList;},activateKey:function(key){var dtnode=(key===null)?null:this.getNodeByKey(key);if(!dtnode){if(this.activeNode){this.activeNode.deactivate();} -this.activeNode=null;return null;} -dtnode.focus();dtnode.activate();return dtnode;},loadKeyPath:function(keyPath,callback){var segList=keyPath.split(this.options.keyPathSeparator);if(segList[0]===""){segList.shift();} -if(segList[0]==this.tnRoot.data.key){this.logDebug("Removed leading root key.");segList.shift();} -keyPath=segList.join(this.options.keyPathSeparator);return this.tnRoot._loadKeyPath(keyPath,callback);},selectKey:function(key,select){var dtnode=this.getNodeByKey(key);if(!dtnode){return null;} -dtnode.select(select);return dtnode;},enableUpdate:function(bEnable){if(this.bEnableUpdate==bEnable){return bEnable;} -this.bEnableUpdate=bEnable;if(bEnable){this.redraw();} -return!bEnable;},count:function(){return this.tnRoot.countChildren();},visit:function(fn,includeRoot){return this.tnRoot.visit(fn,includeRoot);},_createFromTag:function(parentTreeNode,$ulParent){var self=this;$ulParent.find(">li").each(function(){var $li=$(this),$liSpan=$li.find(">span:first"),$liA=$li.find(">a:first"),title,href=null,target=null,tooltip;if($liSpan.length){title=$liSpan.html();}else if($liA.length){title=$liA.html();href=$liA.attr("href");target=$liA.attr("target");tooltip=$liA.attr("title");}else{title=$li.html();var iPos=title.search(/
      =0){title=$.trim(title.substring(0,iPos));}else{title=$.trim(title);}} -var data={title:title,tooltip:tooltip,isFolder:$li.hasClass("folder"),isLazy:$li.hasClass("lazy"),expand:$li.hasClass("expanded"),select:$li.hasClass("selected"),activate:$li.hasClass("active"),focus:$li.hasClass("focused"),noLink:$li.hasClass("noLink")};if(href){data.href=href;data.target=target;} -if($li.attr("title")){data.tooltip=$li.attr("title");} -if($li.attr("id")){data.key=$li.attr("id");} -if($li.attr("data")){var dataAttr=$.trim($li.attr("data"));if(dataAttr){if(dataAttr.charAt(0)!="{"){dataAttr="{"+dataAttr+"}";} -try{$.extend(data,eval("("+dataAttr+")"));}catch(e){throw("Error parsing node data: "+e+"\ndata:\n'"+dataAttr+"'");}}} -var childNode=parentTreeNode.addChild(data);var $ul=$li.find(">ul:first");if($ul.length){self._createFromTag(childNode,$ul);}});},_checkConsistency:function(){},_setDndStatus:function(sourceNode,targetNode,helper,hitMode,accept){var $source=sourceNode?$(sourceNode.span):null,$target=$(targetNode.span);if(!this.$dndMarker){this.$dndMarker=$("
      ").hide().prependTo($(this.divTree).parent());} -if(hitMode==="after"||hitMode==="before"||hitMode==="over"){var pos=$target.offset();switch(hitMode){case"before":this.$dndMarker.removeClass("dynatree-drop-after dynatree-drop-over");this.$dndMarker.addClass("dynatree-drop-before");pos.top-=8;break;case"after":this.$dndMarker.removeClass("dynatree-drop-before dynatree-drop-over");this.$dndMarker.addClass("dynatree-drop-after");pos.top+=8;break;default:this.$dndMarker.removeClass("dynatree-drop-after dynatree-drop-before");this.$dndMarker.addClass("dynatree-drop-over");$target.addClass("dynatree-drop-target");pos.left+=8;} -this.$dndMarker.css({"left":pos.left,"top":pos.top,"z-index":1000}).show();}else{$target.removeClass("dynatree-drop-target");this.$dndMarker.hide();} -if(hitMode==="after"){$target.addClass("dynatree-drop-after");}else{$target.removeClass("dynatree-drop-after");} -if(hitMode==="before"){$target.addClass("dynatree-drop-before");}else{$target.removeClass("dynatree-drop-before");} -if(accept===true){if($source){$source.addClass("dynatree-drop-accept");} -$target.addClass("dynatree-drop-accept");helper.addClass("dynatree-drop-accept");}else{if($source){$source.removeClass("dynatree-drop-accept");} -$target.removeClass("dynatree-drop-accept");helper.removeClass("dynatree-drop-accept");} -if(accept===false){if($source){$source.addClass("dynatree-drop-reject");} -$target.addClass("dynatree-drop-reject");helper.addClass("dynatree-drop-reject");}else{if($source){$source.removeClass("dynatree-drop-reject");} -$target.removeClass("dynatree-drop-reject");helper.removeClass("dynatree-drop-reject");}},_onDragEvent:function(eventName,node,otherNode,event,ui,draggable){var opts=this.options,dnd=this.options.dnd,res=null,nodeTag=$(node.span),hitMode;switch(eventName){case"helper":var $helper=$("
      ").append($(event.target).closest('a').clone());$("ul.dynatree-container",node.tree.divTree).append($helper);$helper.data("dtSourceNode",node);res=$helper;break;case"start":if(node.isStatusNode()){res=false;}else if(dnd.onDragStart){res=dnd.onDragStart(node);} -if(res===false){this.logDebug("tree.onDragStart() cancelled");ui.helper.trigger("mouseup");ui.helper.hide();}else{nodeTag.addClass("dynatree-drag-source");} -break;case"enter":res=dnd.onDragEnter?dnd.onDragEnter(node,otherNode):null;res={over:(res!==false)&&((res===true)||(res==="over")||$.inArray("over",res)>=0),before:(res!==false)&&((res===true)||(res==="before")||$.inArray("before",res)>=0),after:(res!==false)&&((res===true)||(res==="after")||$.inArray("after",res)>=0)};ui.helper.data("enterResponse",res);break;case"over":var enterResponse=ui.helper.data("enterResponse");hitMode=null;if(enterResponse===false){break;}else if(typeof enterResponse==="string"){hitMode=enterResponse;}else{var nodeOfs=nodeTag.offset();var relPos={x:event.pageX-nodeOfs.left,y:event.pageY-nodeOfs.top};var relPos2={x:relPos.x/nodeTag.width(),y:relPos.y/nodeTag.height()};if(enterResponse.after&&relPos2.y>0.75){hitMode="after";}else if(!enterResponse.over&&enterResponse.after&&relPos2.y>0.5){hitMode="after";}else if(enterResponse.before&&relPos2.y<=0.25){hitMode="before";}else if(!enterResponse.over&&enterResponse.before&&relPos2.y<=0.5){hitMode="before";}else if(enterResponse.over){hitMode="over";} -if(dnd.preventVoidMoves){if(node===otherNode){hitMode=null;}else if(hitMode==="before"&&otherNode&&node===otherNode.getNextSibling()){hitMode=null;}else if(hitMode==="after"&&otherNode&&node===otherNode.getPrevSibling()){hitMode=null;}else if(hitMode==="over"&&otherNode&&otherNode.parent===node&&otherNode.isLastSibling()){hitMode=null;}} -ui.helper.data("hitMode",hitMode);} -if(hitMode==="over"&&dnd.autoExpandMS&&node.hasChildren()!==false&&!node.bExpanded){node.scheduleAction("expand",dnd.autoExpandMS);} -if(hitMode&&dnd.onDragOver){res=dnd.onDragOver(node,otherNode,hitMode);} -this._setDndStatus(otherNode,node,ui.helper,hitMode,res!==false);break;case"drop":hitMode=ui.helper.data("hitMode");if(hitMode&&dnd.onDrop){dnd.onDrop(node,otherNode,hitMode,ui,draggable);} -break;case"leave":node.scheduleAction("cancel");ui.helper.data("enterResponse",null);ui.helper.data("hitMode",null);this._setDndStatus(otherNode,node,ui.helper,"out",undefined);if(dnd.onDragLeave){dnd.onDragLeave(node,otherNode);} -break;case"stop":nodeTag.removeClass("dynatree-drag-source");if(dnd.onDragStop){dnd.onDragStop(node);} -break;default:throw"Unsupported drag event: "+eventName;} -return res;},cancelDrag:function(){var dd=$.ui.ddmanager.current;if(dd){dd.cancel();}},lastentry:undefined};$.widget("ui.dynatree",{_init:function(){if(parseFloat($.ui.version)<1.8){if(this.options.debugLevel>=0){_log("warn","ui.dynatree._init() was called; you should upgrade to jquery.ui.core.js v1.8 or higher.");} -return this._create();} -if(this.options.debugLevel>=2){_log("debug","ui.dynatree._init() was called; no current default functionality.");}},_create:function(){var opts=this.options;if(opts.debugLevel>=1){logMsg("Dynatree._create(): version='%s', debugLevel=%o.",$.ui.dynatree.version,this.options.debugLevel);} -this.options.event+=".dynatree";var divTree=this.element.get(0);this.tree=new DynaTree(this);this.tree._load();this.tree.logDebug("Dynatree._init(): done.");},bind:function(){this.unbind();var eventNames="click.dynatree dblclick.dynatree";if(this.options.keyboard){eventNames+=" keypress.dynatree keydown.dynatree";} -this.element.bind(eventNames,function(event){var dtnode=$.ui.dynatree.getNode(event.target);if(!dtnode){return true;} -var tree=dtnode.tree;var o=tree.options;tree.logDebug("event(%s): dtnode: %s",event.type,dtnode);var prevPhase=tree.phase;tree.phase="userEvent";try{switch(event.type){case"click":return(o.onClick&&o.onClick.call(tree,dtnode,event)===false)?false:dtnode._onClick(event);case"dblclick":return(o.onDblClick&&o.onDblClick.call(tree,dtnode,event)===false)?false:dtnode._onDblClick(event);case"keydown":return(o.onKeydown&&o.onKeydown.call(tree,dtnode,event)===false)?false:dtnode._onKeydown(event);case"keypress":return(o.onKeypress&&o.onKeypress.call(tree,dtnode,event)===false)?false:dtnode._onKeypress(event);}}catch(e){var _=null;tree.logWarning("bind(%o): dtnode: %o, error: %o",event,dtnode,e);}finally{tree.phase=prevPhase;}});function __focusHandler(event){event=$.event.fix(event||window.event);var dtnode=$.ui.dynatree.getNode(event.target);return dtnode?dtnode._onFocus(event):false;} -var div=this.tree.divTree;if(div.addEventListener){div.addEventListener("focus",__focusHandler,true);div.addEventListener("blur",__focusHandler,true);}else{div.onfocusin=div.onfocusout=__focusHandler;}},unbind:function(){this.element.unbind(".dynatree");},enable:function(){this.bind();$.Widget.prototype.enable.apply(this,arguments);},disable:function(){this.unbind();$.Widget.prototype.disable.apply(this,arguments);},getTree:function(){return this.tree;},getRoot:function(){return this.tree.getRoot();},getActiveNode:function(){return this.tree.getActiveNode();},getSelectedNodes:function(){return this.tree.getSelectedNodes();},lastentry:undefined});if(parseFloat($.ui.version)<1.8){$.ui.dynatree.getter="getTree getRoot getActiveNode getSelectedNodes";} -$.ui.dynatree.version="$Version: 1.2.1_rc3$";$.ui.dynatree.getNode=function(el){if(el instanceof DynaTreeNode){return el;} -if(el.selector!==undefined){el=el[0];} -while(el){if(el.dtnode){return el.dtnode;} -el=el.parentNode;} -return null;} -$.ui.dynatree.getPersistData=DynaTreeStatus._getTreePersistData;$.ui.dynatree.prototype.options={title:"Dynatree",minExpandLevel:1,imagePath:null,children:null,initId:null,initAjax:null,autoFocus:true,keyboard:true,persist:false,autoCollapse:false,clickFolderMode:3,activeVisible:true,checkbox:false,selectMode:2,fx:null,noLink:false,onClick:null,onDblClick:null,onKeydown:null,onKeypress:null,onFocus:null,onBlur:null,onQueryActivate:null,onQuerySelect:null,onQueryExpand:null,onPostInit:null,onActivate:null,onDeactivate:null,onSelect:null,onExpand:null,onLazyRead:null,onCustomRender:null,onCreate:null,onRender:null,dnd:{onDragStart:null,onDragStop:null,autoExpandMS:1000,preventVoidMoves:true,onDragEnter:null,onDragOver:null,onDrop:null,onDragLeave:null},ajaxDefaults:{cache:false,timeout:0,dataType:"json"},strings:{loading:"Loading…",loadError:"Load error!"},generateIds:false,idPrefix:"dynatree-id-",keyPathSeparator:"/",cookieId:"dynatree",cookie:{expires:null},classNames:{container:"dynatree-container",node:"dynatree-node",folder:"dynatree-folder",empty:"dynatree-empty",vline:"dynatree-vline",expander:"dynatree-expander",connector:"dynatree-connector",checkbox:"dynatree-checkbox",nodeIcon:"dynatree-icon",title:"dynatree-title",noConnector:"dynatree-no-connector",nodeError:"dynatree-statusnode-error",nodeWait:"dynatree-statusnode-wait",hidden:"dynatree-hidden",combinedExpanderPrefix:"dynatree-exp-",combinedIconPrefix:"dynatree-ico-",nodeLoading:"dynatree-loading",hasChildren:"dynatree-has-children",active:"dynatree-active",selected:"dynatree-selected",expanded:"dynatree-expanded",lazy:"dynatree-lazy",focused:"dynatree-focused",partsel:"dynatree-partsel",lastsib:"dynatree-lastsib"},debugLevel:1,lastentry:undefined};if(parseFloat($.ui.version)<1.8){$.ui.dynatree.defaults=$.ui.dynatree.prototype.options;} -$.ui.dynatree.nodedatadefaults={title:null,key:null,isFolder:false,isLazy:false,tooltip:null,href:null,icon:null,addClass:null,noLink:false,activate:false,focus:false,expand:false,select:false,hideCheckbox:false,unselectable:false,children:null,lastentry:undefined};function _initDragAndDrop(tree){var dnd=tree.options.dnd||null;if(dnd&&(dnd.onDragStart||dnd.onDrop)){_registerDnd();} -if(dnd&&dnd.onDragStart){tree.$tree.draggable({addClasses:false,appendTo:"body",containment:false,delay:0,distance:4,revert:false,scroll:true,scrollSpeed:7,scrollSensitivity:10,connectToDynatree:true,helper:function(event){var sourceNode=$.ui.dynatree.getNode(event.target);if(!sourceNode){return"
      ";} -return sourceNode.tree._onDragEvent("helper",sourceNode,null,event,null,null);},start:function(event,ui){},_last:null});} -if(dnd&&dnd.onDrop){tree.$tree.droppable({addClasses:false,tolerance:"intersect",greedy:false,_last:null});}} -var didRegisterDnd=false;var _registerDnd=function(){if(didRegisterDnd){return;} -$.ui.plugin.add("draggable","connectToDynatree",{start:function(event,ui){var draggable=$(this).data("draggable"),sourceNode=ui.helper.data("dtSourceNode")||null;if(sourceNode){draggable.offset.click.top=-2;draggable.offset.click.left=+16;return sourceNode.tree._onDragEvent("start",sourceNode,null,event,ui,draggable);}},drag:function(event,ui){var draggable=$(this).data("draggable"),sourceNode=ui.helper.data("dtSourceNode")||null,prevTargetNode=ui.helper.data("dtTargetNode")||null,targetNode=$.ui.dynatree.getNode(event.target);if(event.target&&!targetNode){var isHelper=$(event.target).closest("div.dynatree-drag-helper,#dynatree-drop-marker").length>0;if(isHelper){return;}} -ui.helper.data("dtTargetNode",targetNode);if(prevTargetNode&&prevTargetNode!==targetNode){prevTargetNode.tree._onDragEvent("leave",prevTargetNode,sourceNode,event,ui,draggable);} -if(targetNode){if(!targetNode.tree.options.dnd.onDrop){noop();}else if(targetNode===prevTargetNode){targetNode.tree._onDragEvent("over",targetNode,sourceNode,event,ui,draggable);}else{targetNode.tree._onDragEvent("enter",targetNode,sourceNode,event,ui,draggable);}}},stop:function(event,ui){var draggable=$(this).data("draggable"),sourceNode=ui.helper.data("dtSourceNode")||null,targetNode=ui.helper.data("dtTargetNode")||null,mouseDownEvent=draggable._mouseDownEvent,eventType=event.type,dropped=(eventType=="mouseup"&&event.which==1);if(!dropped){logMsg("Drag was cancelled");} -if(targetNode){if(dropped){targetNode.tree._onDragEvent("drop",targetNode,sourceNode,event,ui,draggable);} -targetNode.tree._onDragEvent("leave",targetNode,sourceNode,event,ui,draggable);} -if(sourceNode){sourceNode.tree._onDragEvent("stop",sourceNode,null,event,ui,draggable);}}});didRegisterDnd=true;};})(jQuery); \ No newline at end of file diff --git a/web/help/js/jquery.min.js b/web/help/js/jquery.min.js deleted file mode 100644 index ee023370..00000000 --- a/web/help/js/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.1 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
      a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
      "+""+"
      ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
      t
      ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
      ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

      ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
      ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
      ","
      "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
      ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/web/help/js/jquery.treeview.min.js b/web/help/js/jquery.treeview.min.js deleted file mode 100644 index 9dec513e..00000000 --- a/web/help/js/jquery.treeview.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Treeview pre-1.4.1 - jQuery plugin to hide and show branches of a tree - * - * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ - * http://docs.jquery.com/Plugins/Treeview - * - * Copyright (c) 2007 Jörn Zaefferer - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $ - * - */;(function($){$.extend($.fn,{swapClass:function(c1,c2){var c1Elements=this.filter('.'+c1);this.filter('.'+c2).removeClass(c2).addClass(c1);c1Elements.removeClass(c1).addClass(c2);return this;},replaceClass:function(c1,c2){return this.filter('.'+c1).removeClass(c1).addClass(c2).end();},hoverClass:function(className){className=className||"hover";return this.hover(function(){$(this).addClass(className);},function(){$(this).removeClass(className);});},heightToggle:function(animated,callback){animated?this.animate({height:"toggle"},animated,callback):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();if(callback)callback.apply(this,arguments);});},heightHide:function(animated,callback){if(animated){this.animate({height:"hide"},animated,callback);}else{this.hide();if(callback)this.each(callback);}},prepareBranches:function(settings){if(!settings.prerendered){this.filter(":last-child:not(ul)").addClass(CLASSES.last);this.filter((settings.collapsed?"":"."+CLASSES.closed)+":not(."+CLASSES.open+")").find(">ul").hide();}return this.filter(":has(>ul)");},applyClasses:function(settings,toggler){this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event){if(this==event.target)toggler.apply($(this).next());}).add($("a",this)).hoverClass();if(!settings.prerendered){this.filter(":has(>ul:hidden)").addClass(CLASSES.expandable).replaceClass(CLASSES.last,CLASSES.lastExpandable);this.not(":has(>ul:hidden)").addClass(CLASSES.collapsable).replaceClass(CLASSES.last,CLASSES.lastCollapsable);this.prepend("
      ").find("div."+CLASSES.hitarea).each(function(){var classes="";$.each($(this).parent().attr("class").split(" "),function(){classes+=this+"-hitarea ";});$(this).addClass(classes);});}this.find("div."+CLASSES.hitarea).click(toggler);},treeview:function(settings){settings=$.extend({cookieId:"treeview"},settings);if(settings.add){return this.trigger("add",[settings.add]);}if(settings.toggle){var callback=settings.toggle;settings.toggle=function(){return callback.apply($(this).parent()[0],arguments);};}function treeController(tree,control){function handler(filter){return function(){toggler.apply($("div."+CLASSES.hitarea,tree).filter(function(){return filter?$(this).parent("."+filter).length:true;}));return false;};}$("a:eq(0)",control).click(handler(CLASSES.collapsable));$("a:eq(1)",control).click(handler(CLASSES.expandable));$("a:eq(2)",control).click(handler());}function toggler(){$(this).parent().find(">.hitarea").swapClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).swapClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().swapClass(CLASSES.collapsable,CLASSES.expandable).swapClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightToggle(settings.animated,settings.toggle);if(settings.unique){$(this).parent().siblings().find(">.hitarea").replaceClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).replaceClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().replaceClass(CLASSES.collapsable,CLASSES.expandable).replaceClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightHide(settings.animated,settings.toggle);}}function serialize(){function binary(arg){return arg?1:0;}var data=[];branches.each(function(i,e){data[i]=$(e).is(":has(>ul:visible)")?1:0;});$.cookie(settings.cookieId,data.join(""));}function deserialize(){var stored=$.cookie(settings.cookieId);if(stored){var data=stored.split("");branches.each(function(i,e){$(e).find(">ul")[parseInt(data[i])?"show":"hide"]();});}}this.addClass("treeview");var branches=this.find("li").prepareBranches(settings);switch(settings.persist){case"cookie":var toggleCallback=settings.toggle;settings.toggle=function(){serialize();if(toggleCallback){toggleCallback.apply(this,arguments);}};deserialize();break;case"location":var current=this.find("a").filter(function(){return this.href.toLowerCase()==location.href.toLowerCase();});if(current.length){current.addClass("selected").parents("ul, li").add(current.next()).show();}break;}branches.applyClasses(settings,toggler);if(settings.control){treeController(this,settings.control);$(settings.control).show();}return this.bind("add",function(event,branches){$(branches).prev().removeClass(CLASSES.last).removeClass(CLASSES.lastCollapsable).removeClass(CLASSES.lastExpandable).find(">.hitarea").removeClass(CLASSES.lastCollapsableHitarea).removeClass(CLASSES.lastExpandableHitarea);$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings,toggler);});}});var CLASSES=$.fn.treeview.classes={open:"open",closed:"closed",expandable:"expandable",expandableHitarea:"expandable-hitarea",lastExpandableHitarea:"lastExpandable-hitarea",collapsable:"collapsable",collapsableHitarea:"collapsable-hitarea",lastCollapsableHitarea:"lastCollapsable-hitarea",lastCollapsable:"lastCollapsable",lastExpandable:"lastExpandable",last:"last",hitarea:"hitarea"};$.fn.Treeview=$.fn.treeview;})(jQuery); \ No newline at end of file diff --git a/web/help/js/polyfill.object.min.js b/web/help/js/polyfill.object.min.js new file mode 100644 index 00000000..5b0e41ba --- /dev/null +++ b/web/help/js/polyfill.object.min.js @@ -0,0 +1 @@ +"use strict";"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(e){for(var r=[],t=1;t - + + + + + - 6. Advanced Features - - - - - - - - - - + + + + + + + + 6. Advanced Features + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      6. Advanced Features

      - -
      - Beginner's Guide ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      6. Advanced Features

      + +
      +

      -

      Advanced Features

      -


      -


      -

      1. How to share projects.

      -

      2. Patterns usage.

      -

      3. Effective usage of Markers.

      -

      4. Lua usage.

      -


      -
      -

      -

      -

      1. How to share projects.

      -


      -

      A Taseditor project is saved to disk as an .fm3 file. All essential aspects of the work process are saved into this file, making it possible to restore the postponed work in its exact state. The size of such "instant snapshot" may be pretty huge (depending on the Greenzone size, it may take hundreds of megabytes).

      -

      When you want to publish your project in the Internet (for example, as a TASVideos submission), it's better to share only the most important information, but not the whole snapshot of your working process. To do that, choose File -> Save Compact in Taseditor's main menu. The "Save Compact" window will appear, prompting you to select which aspects you want to save to the new FM3 file.

      -

      -

      Binary format of Input – save movie Input in binary form. This option is related to fm2 format, which is the base of the fm3 format. If you uncheck it, Input will be saved to the fm3 file in text format, which will increase file size but leave the possibility to edit it in any text editor. However, Taseditor is much better suited for editing movies, so it's recommended to keep that checkbox set, and avoid changing FM3 projects outside Taseditor. Anyway, in non-compact fm3 projects (saved regular way) Input is always stored in binary.

      -

      Markers – save Markers to the file. The movie Input is always saved to fm3 file, because without it emulator won't be able to open fm3 files. But without Markers the movie replay is still possible, so you can uncheck the checkbox if you don't want to share them. Although this way your fm3 won't differ much from an fm2 movie, so it's recommended to leave that checkbox checked, to share all current Markers and their Notes in the compact project. The file size will increase insignificantly.

      -

      Bookmarks – save all Bookmarks and their branches data to the file. It's recommended to leave this option checked. The file size will increase insignificantly.

      -

      History – save History Log to the file. The file size will increase by several megabytes. Usually there's no need to publish the data. So it's recommended to uncheck this option. When you open an fm3 project with no History Log, Taseditor creates a new History automatically.

      -

      Piano Roll – save current position of vertical scrolling of the Piano Roll, in order to see the exact segment of the movie after loading the compact fm3 file. The file size will increase insignificantly, so you may keep that option checked.

      -

      Selection – save all Selection data to the file. Both current Selection and whole Selection History is saved. The file size will increase insignificantly, but usually there's no need to publish the data. So it's recommended to uncheck this option.

      -

      Greenzone saving options – here you can choose how the Greenzone should be saved. Greenzone is the main factor causing huge project file size. So it's recommended to choose partial saving or not save the Greenzone at all.

      -
        -
      • all frames – save entire Greenzone. The file size will increase dramatically!
      • -
      • every 16th frame – save only every 16th frame. The file size will increase dramatically.
      • -
      • marked frames – save only marked frames. The file size will increase depending on the number of Markers in your project.
      • -
      • don't save – the Greenzone will not be saved. If during the compact saving the Playback cursor is at the very first frame of the movie, there will be no single Greenzone savestate in the fm3 project. But if the cursor was left at some frame in the middle of the movie, the compact fm3 will contain one Greenzone savestate, allowing to restore the emulator state on the Playback cursor frame when you open the project. Since one savestate uses very little disk space, the file is still compact.
      • +

        Advanced Features

        +


        +


        +

        1. How to share projects.

        +

        2. Patterns usage.

        +

        3. Effective usage of Markers.

        +

        4. Lua usage.

        +


        +
        +


        +

        1. How to share projects.

        +


        +

        A Taseditor project is saved to disk as an .fm3 file. All essential aspects of the work process are saved into this file, making it possible to restore the postponed work in its exact state. The size of such "instant snapshot" may be pretty huge (depending on the Greenzone size, it may take hundreds of megabytes).

        +

        When you want to publish your project in the Internet (for example, as a TASVideos submission), it's better to share only the most important information, but not the whole snapshot of your working process. To do that, choose File -> Save Compact in Taseditor's main menu. The "Save Compact" window will appear, prompting you to select which aspects you want to save to the new FM3 file.

        +

        +

        Binary format of Input – save movie Input in binary form. This option is related to fm2 format, which is the base of the fm3 format. If you uncheck it, Input will be saved to the fm3 file in text format, which will increase file size but leave the possibility to edit it in any text editor. However, Taseditor is much better suited for editing movies, so it's recommended to keep that checkbox set, and avoid changing FM3 projects outside Taseditor. Anyway, in non-compact fm3 projects (saved regular way) Input is always stored in binary.

        +

        Markers – save Markers to the file. The movie Input is always saved to fm3 file, because without it emulator won't be able to open fm3 files. But without Markers the movie replay is still possible, so you can uncheck the checkbox if you don't want to share them. Although this way your fm3 won't differ much from an fm2 movie, so it's recommended to leave that checkbox checked, to share all current Markers and their Notes in the compact project. The file size will increase insignificantly.

        +

        Bookmarks – save all Bookmarks and their branches data to the file. It's recommended to leave this option checked. The file size will increase insignificantly.

        +

        History – save History Log to the file. The file size will increase by several megabytes. Usually there's no need to publish the data. So it's recommended to uncheck this option. When you open an fm3 project with no History Log, Taseditor creates a new History automatically.

        +

        Piano Roll – save current position of vertical scrolling of the Piano Roll, in order to see the exact segment of the movie after loading the compact fm3 file. The file size will increase insignificantly, so you may keep that option checked.

        +

        Selection – save all Selection data to the file. Both current Selection and whole Selection History is saved. The file size will increase insignificantly, but usually there's no need to publish the data. So it's recommended to uncheck this option.

        +

        Greenzone saving options – here you can choose how the Greenzone should be saved. Greenzone is the main factor causing huge project file size. So it's recommended to choose partial saving or not save the Greenzone at all.

        +
          +
        • all frames – save entire Greenzone. The file size will increase dramatically!
        • +
        • every 16th frame – save only every 16th frame. The file size will increase dramatically.
        • +
        • marked frames – save only marked frames. The file size will increase depending on the number of Markers in your project.
        • +
        • don't save – the Greenzone will not be saved. If during the compact saving the Playback cursor is at the very first frame of the movie, there will be no single Greenzone savestate in the fm3 project. But if the cursor was left at some frame in the middle of the movie, the compact fm3 will contain one Greenzone savestate, allowing to restore the emulator state on the Playback cursor frame when you open the project. Since one savestate uses very little disk space, the file is still compact.
        -


        -

        Using compact saving you can get an fm3 project being less than 500KB in size, while still sharing all essential data the recipient may need. For example, if you are working in co-authorship with another TASer(s), you will need to share not only Input, but also Markers and Bookmarks. As for the Greenzone, the recipient can recreate it by replaying the project movie in Taseditor.

        -

        On compact saving, your project name receives the "-compact" suffix. Compact saving doesn't replace normal project saving, so if you have any unsaved changes in the project, the asterisk in the window caption will not disappear after Save Compact.

        -

        -

        Besides saving a compact fm3 you can also export movie data to fm2 format, accepted at TASVideos before Taseditor even existed. But in such files you will share only Input. To do that, choose File -> Export to FM2 in Taseditor's main menu. The "Export to FM2" window will appear, prompting you to choose target movie type (1P, 2P, Fourscore).

        -

        Since FM2 format also supports text subtitles, you can use existing Marker Notes as a source for generating movie subtitles. For that, enable the "Convert Marker Notes to Movie Subtitles" checkbox. Then while watching the fm2 file the viewers will see text messages appearing when passing certain frames (the frames where your project had Markers at). If necessary, you can then convert those fm2 subtitles into the commonly used .srt format to post the TAS on Youtube. To do that, right-click the FCEUX window while replaying the subtitled movie and choose "Dump Subtitles to SRT file" command.

        -

        FM2 files can be opened in Taseditor similarly to loading fm3 projects. In the "Open TAS Editor Project" window (File -> Open) switch to the filter "All Files (*.*)" and then choose your fm2 movie file. Taseditor will bring the message box saying that this is not a project file, and will ask confirmation. After you click "Yes" it will create new project using Input and settings from the fm2 file.

        -

        Also, you can import Input from any fm2 or fm3 file using File -> Import Input. This time no new project will be created, but Input of current project will be replaced with Input from the file. This operation is very similar to pasting Input from the Clipboard, it is registered in History Log and can be undone by Ctrl + Z.

        -


        -
        -

        -

        -

        2. Patterns usage.

        -


        -

        When editing Input, TASer actually creates a unique sequence of presses and releases for every button of joypad. But, despite the uniqueness, this large sequence still contains many typical segments, which are are short sequences of presses and releases that repeat many times in succession, or appear many times in different places of the movie.

        -

        To speed up the work, you can remember the most typical or frequent sequences as patterns, to be able to put them with a couple of clicks, not drawing every single buttonpress manually each time.

        -

        Patterns are useful in several cases:

        -
          -
        • when one sequence is frequently used in the movie (for example, an accurate alternation of pressing and releasing the B button)
        • -
        • when you need the same sequence for several buttons (for example, alternating L and R)
        • -
        • when a certain sequence needs to be drawn (or redrawn) many times (for example, making a running start by tapping R twice)
        • +


          +

          Using compact saving you can get an fm3 project being less than 500KB in size, while still sharing all essential data the recipient may need. For example, if you are working in co-authorship with another TASer(s), you will need to share not only Input, but also Markers and Bookmarks. As for the Greenzone, the recipient can recreate it by replaying the project movie in Taseditor.

          +

          On compact saving, your project name receives the "-compact" suffix. Compact saving doesn't replace normal project saving, so if you have any unsaved changes in the project, the asterisk in the window caption will not disappear after Save Compact.

          +

          +

          Besides saving a compact fm3 you can also export movie data to fm2 format, accepted at TASVideos before Taseditor even existed. But in such files you will share only Input. To do that, choose File -> Export to FM2 in Taseditor's main menu. The "Export to FM2" window will appear, prompting you to choose target movie type (1P, 2P, Fourscore).

          +

          Since FM2 format also supports text subtitles, you can use existing Marker Notes as a source for generating movie subtitles. For that, enable the "Convert Marker Notes to Movie Subtitles" checkbox. Then while watching the fm2 file the viewers will see text messages appearing when passing certain frames (the frames where your project had Markers at). If necessary, you can then convert those fm2 subtitles into the commonly used .srt format to post the TAS on Youtube. To do that, right-click the FCEUX window while replaying the subtitled movie and choose "Dump Subtitles to SRT file" command.

          +

          FM2 files can be opened in Taseditor similarly to loading fm3 projects. In the "Open TAS Editor Project" window (File -> Open) switch to the filter "All Files (*.*)" and then choose your fm2 movie file. Taseditor will bring the message box saying that this is not a project file, and will ask confirmation. After you click "Yes" it will create new project using Input and settings from the fm2 file.

          +

          Also, you can import Input from any fm2 or fm3 file using File -> Import Input. This time no new project will be created, but Input of current project will be replaced with Input from the file. This operation is very similar to pasting Input from the Clipboard, it is registered in History Log and can be undone by Ctrl + Z.

          +


          +
          +


          +

          2. Patterns usage.

          +


          +

          When editing Input, TASer actually creates a unique sequence of presses and releases for every button of joypad. But, despite the uniqueness, this large sequence still contains many typical segments, which are are short sequences of presses and releases that repeat many times in succession, or appear many times in different places of the movie.

          +

          To speed up the work, you can remember the most typical or frequent sequences as patterns, to be able to put them with a couple of clicks, not drawing every single buttonpress manually each time.

          +

          Patterns are useful in several cases:

          +
            +
          • when one sequence is frequently used in the movie (for example, an accurate alternation of pressing and releasing the B button)
          • +
          • when you need the same sequence for several buttons (for example, alternating L and R)
          • +
          • when a certain sequence needs to be drawn (or redrawn) many times (for example, making a running start by tapping R twice)
          -

          Some of the most obvious patterns are already added by author. To add your own pattern you need to edit the taseditor_patterns.txt file in any text editor (like Notepad), this file is stored in /tools subfolder of FCEUX main folder. Every second line in this file constitutes an encoded sequence of button states. The code is straightforward: "button pressed" is encoded by 1, "button released" – by 0.

          -

          Every pattern is looped, which means, when a long sequence of Input is created using a short pattern, the pattern is repeated the necessary amount of times to fill the whole given interval.

          -

          -

          After adding or editing the patterns file, restart Taseditor to reread the file changes. The list of all available patterns is always in the upper right corner of the TAS Editor window. To change the current pattern, enter that menu and click the needed pattern name. For easy orientation in patterns it's recommended to call each pattern by a distinct name that reflects its in-game meaning.

          -

          To apply current pattern, Taseditor needs to know the beginning and the end of the interval where the chosen button is going to be pressed and released according to the rule. There are 3 different ways to apply a pattern:

          -

          Example 1. Point and click the start frame (click in any Piano Roll column except the icons column), thus selecting that frame. Then hold the Alt key and left-click the end frame in the column of the button you are editing. In the interval between those two frames you will get the needed sequence of the chosen button presses. This method is rather handy when the start frame is already selected by previous clicks in Piano Roll, and you only need to to hold down Alt and click the end frame.

          -

          Example 2. Left-click the start frame in the column of the button you are editing, and hold the mouse button to start drawing. Hold Alt and move the mouse cursor up or down. This way you will be drawing the pattern sequence of buttonpresses.

          -

          Example 3. Select a range of frames, then hold Alt and left-click on the edited button symbol in the Piano Roll Header. The pattern will be applied to the selected area.

          -


          -

          When using traditional method of TASing you are also able to apply patterns to recorded sequences, although in a less convenient manner. To do that you should set the "Use pattern" checkbox on Recorder panel. Before that you may want to record the buttons you don't need to alternate (record them without using patterns), and then record the needed button(s) with pattern, using the "Superimpose" function for the segment.

          -

          For example, you need to record a burst of fire while jumping over the pit. At first, record that jump without shooting, then return the Playback cursor to the beginning of the segment (by jumping to the Bookmark left here), check "Superimpose" and "Use pattern", hold the B button and unpause the emulation. You'll see how the shooting Input superimposes over jump Input.

          -

          Before Taseditor there was the "Autofire" concept similar to patterns. But due to inconveniences of the Recording method that feature was rarely used, because when you are typing Input it's usually easier to press and release the needed buttons manually. So if you stick to traditional method of TASing, you won't likely use patterns. But in the non-linear or semi-automatic TASing, patterns are drawn as quickly as regular buttonpresses, so that's where they can really speed up the work.

          -


          -

          Patterns are used when creating sequences for a single button. But when you want to use a typical macro involving several buttons, use Copy/Paste.

          -


          -
          -

          -

          -

          3. Effective usage of Markers.

          -


          -

          Markers exist to simplify complicated situations by structurizing the problem. When the game requires you to perform (or think over) several complex actions, you should break the large segment into separate intervals, in order to understand clearly where one action stops and another one starts. Even if the initial subdividing appears to be wrong, it still helps you to get thoughts in order.

          -

          Obviously, you are not expected to set Markers on commonplace segments, most of which aren't even polished (e.g. where it's enough to hold R to win). But key moments and memorable situations of the movie should be marked and commented with Notes. It will help you to keep the whole picture of the project in mind and navigate the movie by text.

          -

          No need to write works of literature inside the Notes. You may just confine yourself with simple label words, numbers, tags. Invent the words on the fly, but try to keep systematic approach. As in, if at the beginning of the first level (on the transition screen) you've set a Marker with the Note "level 1 start", you should also write "level 2 start" at the beginning of the second level, and not "act II begin" or something. During the creation of TAS you naturally form a unique glossary in your mind using various terms that are topical for that specific game. And the more systematic approach you apply to writing the Notes, the easier it will be to describe another (similar) segment and understand its task. The easier it'll be to find similar Input segments, recalling only their vague in-game appearance.

          -

          The tasks you meet in video games are often repeatable. Details and environment may be different, but player actions remain more or less the same. In some cases you can just copy the Input (solution of the similar task) from the previous level, and it will successfully sync with the new in-game situation (probably after a little adjustment). Though, after the copy/paste it's recommended to diversify the Input to prevent the TAS viewers from noticing the repetition and getting bored.

          -

          For example, at the beginning of many levels in Super Mario Bros you need to use the same button sequence to accelerate to maximum speed optimally. Let's imagine, you are honestly commenting Input during TASing. Then in World 1-1 in the acceleration section you probably left a Note with words like "acceleration" or similar. Now, when you start creating Input for a segment with that task again, in a new level you put a Marker at the beginning of the segment and write a Note, describing your current task. Obviously enough, you are going to use the word "acceleration" there as well, because you need to accelerate.

          -

          -

          And that's where you can use Taseditor's function of automatic searching for similar Notes. Leave the Playback cursor inside the current segment and press the "Similar" button at the bottom of the Toolbox. The Selection cursor will instantly jump to the Marker that contains the most resembling Note, in Taseditor's opinion. Most likely, it will be the Marker left at the beginning of the acceleration segment in the World 1-1. Therefore you can instantly select all Input in that segment by pressing Ctrl + A, then copy the Input to the Clipboard (Ctrl + C), return to the current segment (press Shift twice) and paste from the Clipboard (Ctrl + V).

          -

          If the first search result doesn't bring you to the intended segment, you can press the "More" button to try next result of the search. Usually the right segment is among the first offered finds, granted that you marked the segment with a sensible Note.

          -

          Interesting fact: while writing the Note for the second appearance of the acceleration segment, you use the word "acceleration" without an intent to correlate to previous cases, but only according to the in-game situation. So you are not expected to actually remember the text of old Notes. The right words will come to your mind in the right time.

          -

          This way, right during the TASing process you form a library of useful Input combinations, not unlike the pattern list described above, except that you don't have to purposely prepare the button sequences – they appear natural way during the segments shaping and optimization, and they are stored inside the movie, not in an external file. And when you improve a combination for some segment (e.g. find a faster way to accelerate), you can easily find and fix all related segments with similar button sequence. Also, here you don't have to remember the exact description or the name of the needed sequence, because, if you use systematic approach to describe tasks, the words will partially match (and a perfect match is not required, since the searching algorithm is rather smart).

          -

          The auto-search is also useful when you need to jump between two (or more) related segments, located far from each other in the movie. Scrolling the Piano Roll with the mouse wheel or jumping through dozens of Markers from one segment to another is not as handy as clicking the "Similar" or "More" button. To let the algorithm instantly find the twin segment (or the source segment and the destination segment), consider using some unique word in their Notes, one that isn't used in other places of the movie.

          -

          For example, in the "Megaman" game each robot master must be beaten twice (second time it's in the end of the game). It's logical to suppose that both battles will be entitled by Marker Notes containing the name of the robot and the word "boss" or "fight", or something like that. As a result, when the Playback cursor is in one of those 2 places, pressing the "Similar" button will get you to another one.

          -

          In this example the proper words for the Notes text are no-brainer, yet they are unique enough not to repeat in other places (at least not in that combination), so the auto-search will work perfectly. In a different case you may have to invent a unique label, but usually the first description you think of is enough.

          -


          -

          -

          You can also use standard search for Note text. For example, it's common to leave a Note beginning with the "TODO" word at some places where you are not sure the best solution is found (the segment Input is optimal). So, when you have mood to make fixes, you could skim through all Markers with that tag by bringing the "Find Note" window (Ctrl + F) and typing the word "TODO" to search for.

          -


          -

          If you don't like all these big ideas with Markers, you can TAS without them. After all, many games provide rather simple tasks for a TASer, they don't require a highly organized approach to the solving process. If the problem can be solved on impulse, don't spend time on preparation and fortification. Markers provide advantages only in long-term goals.

          -

          So, just like in programming, in most cases you can successfully write the so-called "dirty code" (here it would be a project without Markers and Notes) that is fast to create, but hard to maintain and extend. Or you can make a lovingly formatted project which is nice to watch and modify. Since TASers have to modify their movies very often (in order to beat previous records), the today's time costs for the project formatting are likely to be repaid by the fact that the looks of the project motivate to continue the work on it.

          -


          -
          -

          -

          -

          4. Lua usage.

          -


          -

          With the Lua language you can write scripts that can be executed by FCEUX along with game emulation. Writing scripts requires minimal programming skill, while the range of possibilities is pretty huge. You can create your own TAS tools, modify the game at the time of execution, have access to images and sound on the fly, send data via network or record it to disk, etc. And you can make custom extensions for TAS Editor.

          -

          To master the Lua language completely you would need to read its documentation and gain actual experience, but for making simple scripts it should be enough to read this Manual and the Lua chapter in FCEUX docs. At first, try to run scripts created for FCEUX by various people. They are stored in the /luaScripts subfolder. Each script is a text file with .lua extension, such file may be created and modified in any text editor. Before running scripts you need to open some game ROM in FCEUX. To run a script, open the Lua console (File -> Lua -> New Lua Script Window), in this window press the "Browse" button and load the script file, then press "Run". If emulator is paused, either unpause it or advance a frame to activate the script. As for the Lua console, the window may be hidden or minimized.

          -

          Program code in Lua scripts for FCEUX usually consists of 2 parts: the first part is executed once the script is activated, another part runs on certain emulation events, such as the end of a frame emulation, loading a savestate and so on.

          -

          The first part, which runs on script activation, is usually executed only once (unless you made an infinite loop in it). The code is executed line by line, from top to down. Usually the task of that part is to initialize global variables and register functions to be launched by FCEUX when certain events occur.

          -

          In most of cases the main code of the script is contained in the single function that is automatically executed at the end of every frame. For example, this is how Mario hitbox drawing code for SMB may look:

          -


          -
      - - - +

      Some of the most obvious patterns are already added by author. To add your own pattern you need to edit the taseditor_patterns.txt file in any text editor (like Notepad), this file is stored in /tools subfolder of FCEUX main folder. Every second line in this file constitutes an encoded sequence of button states. The code is straightforward: "button pressed" is encoded by 1, "button released" – by 0.

      +

      Every pattern is looped, which means, when a long sequence of Input is created using a short pattern, the pattern is repeated the necessary amount of times to fill the whole given interval.

      +

      +

      After adding or editing the patterns file, restart Taseditor to reread the file changes. The list of all available patterns is always in the upper right corner of the TAS Editor window. To change the current pattern, enter that menu and click the needed pattern name. For easy orientation in patterns it's recommended to call each pattern by a distinct name that reflects its in-game meaning.

      +

      To apply current pattern, Taseditor needs to know the beginning and the end of the interval where the chosen button is going to be pressed and released according to the rule. There are 3 different ways to apply a pattern:

      +

      Example 1. Point and click the start frame (click in any Piano Roll column except the icons column), thus selecting that frame. Then hold the Alt key and left-click the end frame in the column of the button you are editing. In the interval between those two frames you will get the needed sequence of the chosen button presses. This method is rather handy when the start frame is already selected by previous clicks in Piano Roll, and you only need to to hold down Alt and click the end frame.

      +

      Example 2. Left-click the start frame in the column of the button you are editing, and hold the mouse button to start drawing. Hold Alt and move the mouse cursor up or down. This way you will be drawing the pattern sequence of buttonpresses.

      +

      Example 3. Select a range of frames, then hold Alt and left-click on the edited button symbol in the Piano Roll Header. The pattern will be applied to the selected area.

      +


      +

      When using traditional method of TASing you are also able to apply patterns to recorded sequences, although in a less convenient manner. To do that you should set the "Use pattern" checkbox on Recorder panel. Before that you may want to record the buttons you don't need to alternate (record them without using patterns), and then record the needed button(s) with pattern, using the "Superimpose" function for the segment.

      +

      For example, you need to record a burst of fire while jumping over the pit. At first, record that jump without shooting, then return the Playback cursor to the beginning of the segment (by jumping to the Bookmark left here), check "Superimpose" and "Use pattern", hold the B button and unpause the emulation. You'll see how the shooting Input superimposes over jump Input.

      +

      Before Taseditor there was the "Autofire" concept similar to patterns. But due to inconveniences of the Recording method that feature was rarely used, because when you are typing Input it's usually easier to press and release the needed buttons manually. So if you stick to traditional method of TASing, you won't likely use patterns. But in the non-linear or semi-automatic TASing, patterns are drawn as quickly as regular buttonpresses, so that's where they can really speed up the work.

      +


      +

      Patterns are used when creating sequences for a single button. But when you want to use a typical macro involving several buttons, use Copy/Paste.

      +


      +
      +


      +

      3. Effective usage of Markers.

      +


      +

      Markers exist to simplify complicated situations by structurizing the problem. When the game requires you to perform (or think over) several complex actions, you should break the large segment into separate intervals, in order to understand clearly where one action stops and another one starts. Even if the initial subdividing appears to be wrong, it still helps you to get thoughts in order.

      +

      Obviously, you are not expected to set Markers on commonplace segments, most of which aren't even polished (e.g. where it's enough to hold R to win). But key moments and memorable situations of the movie should be marked and commented with Notes. It will help you to keep the whole picture of the project in mind and navigate the movie by text.

      +

      No need to write works of literature inside the Notes. You may just confine yourself with simple label words, numbers, tags. Invent the words on the fly, but try to keep systematic approach. As in, if at the beginning of the first level (on the transition screen) you've set a Marker with the Note "level 1 start", you should also write "level 2 start" at the beginning of the second level, and not "act II begin" or something. During the creation of TAS you naturally form a unique glossary in your mind using various terms that are topical for that specific game. And the more systematic approach you apply to writing the Notes, the easier it will be to describe another (similar) segment and understand its task. The easier it'll be to find similar Input segments, recalling only their vague in-game appearance.

      +

      The tasks you meet in video games are often repeatable. Details and environment may be different, but player actions remain more or less the same. In some cases you can just copy the Input (solution of the similar task) from the previous level, and it will successfully sync with the new in-game situation (probably after a little adjustment). Though, after the copy/paste it's recommended to diversify the Input to prevent the TAS viewers from noticing the repetition and getting bored.

      +

      For example, at the beginning of many levels in Super Mario Bros you need to use the same button sequence to accelerate to maximum speed optimally. Let's imagine, you are honestly commenting Input during TASing. Then in World 1-1 in the acceleration section you probably left a Note with words like "acceleration" or similar. Now, when you start creating Input for a segment with that task again, in a new level you put a Marker at the beginning of the segment and write a Note, describing your current task. Obviously enough, you are going to use the word "acceleration" there as well, because you need to accelerate.

      +

      +

      And that's where you can use Taseditor's function of automatic searching for similar Notes. Leave the Playback cursor inside the current segment and press the "Similar" button at the bottom of the Toolbox. The Selection cursor will instantly jump to the Marker that contains the most resembling Note, in Taseditor's opinion. Most likely, it will be the Marker left at the beginning of the acceleration segment in the World 1-1. Therefore you can instantly select all Input in that segment by pressing Ctrl + A, then copy the Input to the Clipboard (Ctrl + C), return to the current segment (press Shift twice) and paste from the Clipboard (Ctrl + V).

      +

      If the first search result doesn't bring you to the intended segment, you can press the "More" button to try next result of the search. Usually the right segment is among the first offered finds, granted that you marked the segment with a sensible Note.

      +

      Interesting fact: while writing the Note for the second appearance of the acceleration segment, you use the word "acceleration" without an intent to correlate to previous cases, but only according to the in-game situation. So you are not expected to actually remember the text of old Notes. The right words will come to your mind in the right time.

      +

      This way, right during the TASing process you form a library of useful Input combinations, not unlike the pattern list described above, except that you don't have to purposely prepare the button sequences – they appear natural way during the segments shaping and optimization, and they are stored inside the movie, not in an external file. And when you improve a combination for some segment (e.g. find a faster way to accelerate), you can easily find and fix all related segments with similar button sequence. Also, here you don't have to remember the exact description or the name of the needed sequence, because, if you use systematic approach to describe tasks, the words will partially match (and a perfect match is not required, since the searching algorithm is rather smart).

      +

      The auto-search is also useful when you need to jump between two (or more) related segments, located far from each other in the movie. Scrolling the Piano Roll with the mouse wheel or jumping through dozens of Markers from one segment to another is not as handy as clicking the "Similar" or "More" button. To let the algorithm instantly find the twin segment (or the source segment and the destination segment), consider using some unique word in their Notes, one that isn't used in other places of the movie.

      +

      For example, in the "Megaman" game each robot master must be beaten twice (second time it's in the end of the game). It's logical to suppose that both battles will be entitled by Marker Notes containing the name of the robot and the word "boss" or "fight", or something like that. As a result, when the Playback cursor is in one of those 2 places, pressing the "Similar" button will get you to another one.

      +

      In this example the proper words for the Notes text are no-brainer, yet they are unique enough not to repeat in other places (at least not in that combination), so the auto-search will work perfectly. In a different case you may have to invent a unique label, but usually the first description you think of is enough.

      +


      +

      +

      You can also use standard search for Note text. For example, it's common to leave a Note beginning with the "TODO" word at some places where you are not sure the best solution is found (the segment Input is optimal). So, when you have mood to make fixes, you could skim through all Markers with that tag by bringing the "Find Note" window (Ctrl + F) and typing the word "TODO" to search for.

      +


      +

      If you don't like all these big ideas with Markers, you can TAS without them. After all, many games provide rather simple tasks for a TASer, they don't require a highly organized approach to the solving process. If the problem can be solved on impulse, don't spend time on preparation and fortification. Markers provide advantages only in long-term goals.

      +

      So, just like in programming, in most cases you can successfully write the so-called "dirty code" (here it would be a project without Markers and Notes) that is fast to create, but hard to maintain and extend. Or you can make a lovingly formatted project which is nice to watch and modify. Since TASers have to modify their movies very often (in order to beat previous records), the today's time costs for the project formatting are likely to be repaid by the fact that the looks of the project motivate to continue the work on it.

      +


      +
      +


      +

      4. Lua usage.

      +


      +

      With the Lua language you can write scripts that can be executed by FCEUX along with game emulation. Writing scripts requires minimal programming skill, while the range of possibilities is pretty huge. You can create your own TAS tools, modify the game at the time of execution, have access to images and sound on the fly, send data via network or record it to disk, etc. And you can make custom extensions for TAS Editor.

      +

      To master the Lua language completely you would need to read its documentation and gain actual experience, but for making simple scripts it should be enough to read this Manual and the Lua chapter in FCEUX docs. At first, try to run scripts created for FCEUX by various people. They are stored in the /luaScripts subfolder. Each script is a text file with .lua extension, such file may be created and modified in any text editor. Before running scripts you need to open some game ROM in FCEUX. To run a script, open the Lua console (File -> Lua -> New Lua Script Window), in this window press the "Browse" button and load the script file, then press "Run". If emulator is paused, either unpause it or advance a frame to activate the script. As for the Lua console, the window may be hidden or minimized.

      +

      Program code in Lua scripts for FCEUX usually consists of 2 parts: the first part is executed once the script is activated, another part runs on certain emulation events, such as the end of a frame emulation, loading a savestate and so on.

      +

      The first part, which runs on script activation, is usually executed only once (unless you made an infinite loop in it). The code is executed line by line, from top to down. Usually the task of that part is to initialize global variables and register functions to be launched by FCEUX when certain events occur.

      +

      In most of cases the main code of the script is contained in the single function that is automatically executed at the end of every frame. For example, this is how Mario hitbox drawing code for SMB may look:

      +


      +
      +

      marioWidth = 16

      -

      marioHeight = 32

      -


      -

      function everyframe()

      -

             marioX = memory.readbyte(0x3AD)

      -

             marioY = memory.readbyte(0xCE)

      -

             gui.drawbox(marioX, marioY, marioX + marioWidth, marioY + marioHeight)

      -

      end

      -


      -

      emu.registerafter(everyframe)

      -
      + + +
      +

      marioWidth = 16

      +

      marioHeight = 32

      +


      +

      function everyframe()

      +

             marioX = memory.readbyte(0x3AD)

      +

             marioY = memory.readbyte(0xCE)

      +

             gui.drawbox(marioX, marioY, marioX + marioWidth, marioY + marioHeight)

      +

      end

      +


      +

      emu.registerafter(everyframe)

      +
      -


      -

      When activating this script, FCEUX creates and initializes two variables ("marioWidth" and "marioHeight"), then registers the function called everyframe() to the "frame end" event (registerafter). After that the text ends and the script finishes its execution, but the registered function remains in emulator memory, and if you unpause it or press Frame Advance, after every frame it will run the code stored within the everyframe() function. That code consists of 3 lines. The first two create variables for the hitbox position and initialize them with current values from RAM of the emulated console. The third line draws graphics over the game picture output.

      -

      Actual RAM addresses can be found in public resources (like http://tasvideos.org/GameResources/NES/SuperMarioBros.html) or found on your own using the Cheat Search tool or the RAM Search tool built in FCEUX. In this case we know that Mario's X position is stored in memory address 0x3AD, and his Y position is in 0xCE. So, the script just takes their current values and draws the rectangle in the corresponding screen position. Sometimes there's need to recalculate the values to translate the in-game world coordinates into on-screen coordinates, but in this case they match.

      -

      The standard functions readbyte(), drawbox() and other useful functions are described in the FCEUX documentation. It also describes how to use mathematical expressions and make loops and conditions.

      -

      The standard functions available only when Taseditor is engaged are listed in the Reference. Using all this knowledge you can not only draw and write messages over the emulator screen, but also control Playback and Selection, and most importantly, modify the movie Input and Markers.

      -

      For example, this code copies one joypad Input to the second one's place:

      -


      -
      - - - +


      +

      When activating this script, FCEUX creates and initializes two variables ("marioWidth" and "marioHeight"), then registers the function called everyframe() to the "frame end" event (registerafter). After that the text ends and the script finishes its execution, but the registered function remains in emulator memory, and if you unpause it or press Frame Advance, after every frame it will run the code stored within the everyframe() function. That code consists of 3 lines. The first two create variables for the hitbox position and initialize them with current values from RAM of the emulated console. The third line draws graphics over the game picture output.

      +

      Actual RAM addresses can be found in public resources (like http://tasvideos.org/GameResources/NES/SuperMarioBros.html) or found on your own using the Cheat Search tool or the RAM Search tool built in FCEUX. In this case we know that Mario's X position is stored in memory address 0x3AD, and his Y position is in 0xCE. So, the script just takes their current values and draws the rectangle in the corresponding screen position. Sometimes there's need to recalculate the values to translate the in-game world coordinates into on-screen coordinates, but in this case they match.

      +

      The standard functions readbyte(), drawbox() and other useful functions are described in the FCEUX documentation. It also describes how to use mathematical expressions and make loops and conditions.

      +

      The standard functions available only when Taseditor is engaged are listed in the Reference. Using all this knowledge you can not only draw and write messages over the emulator screen, but also control Playback and Selection, and most importantly, modify the movie Input and Markers.

      +

      For example, this code copies one joypad Input to the second one's place:

      +


      +
      +

      function doCopy()

      -

             selection_table = taseditor.getselection()

      -

             if (selection_table ~= nil) then

      -

                     for i = 1, #selection_table do

      -

                             selected_frame = selection_table[i]

      -

                             joypad1data = taseditor.getinput(selected_frame, 1)

      -

                             taseditor.submitinputchange(selected_frame, 2, joypad1data)

      -

                     end

      -

                     taseditor.applyinputchanges("Copy 1P->2P")

      -

             end

      -

      end

      -


      -

      taseditor.registermanual(doCopy, "Copy 1P to 2P")

      -
      + + +
      +

      function doCopy()

      +

             selection_table = taseditor.getselection()

      +

             if (selection_table ~= nil) then

      +

                     for i = 1, #selection_table do

      +

                             selected_frame = selection_table[i]

      +

                             joypad1data = taseditor.getinput(selected_frame, 1)

      +

                             taseditor.submitinputchange(selected_frame, 2, joypad1data)

      +

                     end

      +

                     taseditor.applyinputchanges("Copy 1P->2P")

      +

             end

      +

      end

      +


      +

      taseditor.registermanual(doCopy, "Copy 1P to 2P")

      +
      -


      -

      When launching this script, FCEUX registers the doCopy() function to the event of pressing the "Run function" button (registermanual). Now any click on the button will run the code of that function, consisting of 9 lines. At first, the function gets information about Selection from Taseditor, and if it's not blank (i.e. at least one frame is selected in the Piano Roll) it runs the FOR loop, going through all the selected frames from the first to the last. For each selected frame the function requests the Input of the first player from Taseditor (and stores this data to the "joypad1data" variable), then it submits the claim to change the second player Input for that frame. All these submissions are accumulated in Taseditor memory until the FOR loop ends, after that they all are applied by calling the applyinputchanges(). As a result, the second joypad in the selected range of frames contains the same Input as the first joypad.

      -

      -

      This simple script is already a useful mini-tool that may be needed when making a TAS for 2 or more players. Launch it, and while TASing you will be able to select a range of frames in the Piano Roll and click the "Copy 1P to 2P" button (or press the "Run Manual Lua function" hotkey) to synchronize both players. Every time the script work results in an Input change, the Greenzone is automatically truncated, and a new item is added to the History Log, allowing you to undo the changes done by the script. This way you've got a feature completely integrated into Taseditor, and you've programmed the behavior of the feature yourself.

      -

      Even though you can successfully TAS without Lua knowledge, its support can save you much time and even hint on a less obvious solutions during the Input optimization (or more exactly, during the game Output analysis).

      -

      Videogames often hide important details of the situation, and TASer has to watch memory state directly in order to know for sure what's going on and to precisely perceive the optimality factors while polishing segments.

      -

      For example, many games don't show boss HP on screen. So, to know exactly the damage you inflict, you need to watch the numeric value of the corresponding RAM address in the Memory Watch window. And when there is a plenty of hidden factors (for example, several timers of invulnerability and boss attack, and some special counters of the player character), TASer needs to watch and analyze many memory addresses as they change according to different rules. In this case an on-screen visualization of some data would be huge helper. For example, boss HP can be displayed as a bar or a number above his head, and a red color can indicate the damage frames or other events. As a result, your mind is relieved by moving from deciphering an abstract data format to the format that instantly delivers the main idea (e.g. "the boss was damaged", "good/bad").

      -

      So it's recommended to learn Lua at least to the level of being able to sensibly modify others' scripts. For the long time FCEUX existed, people wrote and published a lot of scripts serving for various purposes, and you'll probably only need to change some RAM addresses to adjust a script to your game. Oftentimes it also makes sense to ask for help at TASVideos forums.

      -


      -
      -


      -

      The Taseditor guide is over. If you were reading carefully, you should now know everything necessary to make a TAS up to the high standards of TASVideos. The only thing left is to gain an experience in real work, master some actions to automatism in order to feel no trace of routine and have fun from the process of armed playthrough and investigation of games.

      -


      -


      -


      -


      -


      +


      +

      When launching this script, FCEUX registers the doCopy() function to the event of pressing the "Run function" button (registermanual). Now any click on the button will run the code of that function, consisting of 9 lines. At first, the function gets information about Selection from Taseditor, and if it's not blank (i.e. at least one frame is selected in the Piano Roll) it runs the FOR loop, going through all the selected frames from the first to the last. For each selected frame the function requests the Input of the first player from Taseditor (and stores this data to the "joypad1data" variable), then it submits the claim to change the second player Input for that frame. All these submissions are accumulated in Taseditor memory until the FOR loop ends, after that they all are applied by calling the applyinputchanges(). As a result, the second joypad in the selected range of frames contains the same Input as the first joypad.

      +

      +

      This simple script is already a useful mini-tool that may be needed when making a TAS for 2 or more players. Launch it, and while TASing you will be able to select a range of frames in the Piano Roll and click the "Copy 1P to 2P" button (or press the "Run Manual Lua function" hotkey) to synchronize both players. Every time the script work results in an Input change, the Greenzone is automatically truncated, and a new item is added to the History Log, allowing you to undo the changes done by the script. This way you've got a feature completely integrated into Taseditor, and you've programmed the behavior of the feature yourself.

      +

      Even though you can successfully TAS without Lua knowledge, its support can save you much time and even hint on a less obvious solutions during the Input optimization (or more exactly, during the game Output analysis).

      +

      Videogames often hide important details of the situation, and TASer has to watch memory state directly in order to know for sure what's going on and to precisely perceive the optimality factors while polishing segments.

      +

      For example, many games don't show boss HP on screen. So, to know exactly the damage you inflict, you need to watch the numeric value of the corresponding RAM address in the Memory Watch window. And when there is a plenty of hidden factors (for example, several timers of invulnerability and boss attack, and some special counters of the player character), TASer needs to watch and analyze many memory addresses as they change according to different rules. In this case an on-screen visualization of some data would be huge helper. For example, boss HP can be displayed as a bar or a number above his head, and a red color can indicate the damage frames or other events. As a result, your mind is relieved by moving from deciphering an abstract data format to the format that instantly delivers the main idea (e.g. "the boss was damaged", "good/bad").

      +

      So it's recommended to learn Lua at least to the level of being able to sensibly modify others' scripts. For the long time FCEUX existed, people wrote and published a lot of scripts serving for various purposes, and you'll probably only need to change some RAM addresses to adjust a script to your game. Oftentimes it also makes sense to ask for help at TASVideos forums.

      +


      +
      +


      +

      The Taseditor guide is over. If you were reading carefully, you should now know everything necessary to make a TAS up to the high standards of TASVideos. The only thing left is to gain an experience in real work, master some actions to automatism in order to feel no trace of routine and have fun from the process of armed playthrough and investigation of games.

      +


      +


      +


      +


      +


      -

      Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

      - - - + + + + + +
      + + + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - - - - diff --git a/web/help/taseditor/BeginnersGuide.html b/web/help/taseditor/BeginnersGuide.html index 333b351e..131344fb 100644 --- a/web/help/taseditor/BeginnersGuide.html +++ b/web/help/taseditor/BeginnersGuide.html @@ -1,97 +1,292 @@ - - + + + + + - Beginner's Guide - - - - - - - - - - + + + + + + + + Beginner's Guide + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Beginner's Guide

      - -
      -
      - Previous - - Next - -
      -
      -
      -
      - -

      -

      Beginner's Guide

      -


      -


      -

      This part of the documentation is presented in the form of a textbook on TASing.

      -

      It explains the practice of using Taseditor and describes the mechanism of conventional TASing methods.

      -

      The course will be useful both to people who wish to learn TASing and to already experienced TASers who are open to new trends and wish to improve their knowledge.

      -


      -


      -

      Introduction

      -

      General overview of TAS Editor's goals and features

      -


      -

      Program Interface

      -

      Learning the fundamentals of the program usage

      -


      -

      TASing Process

      -

      The author's vision of the competent working process

      -


      -

      TASing Methodology

      -

      Dissection of the Input improvement methods

      -


      -

      Program customization

      -

      Detailed review of all settings

      -


      -

      Advanced Features

      -

      Describing the additional possibilities

      -


      -


      -


      -


      -


      -

      -

      Created with the Personal Edition of HelpNDoc: Full-featured Kindle eBooks generator

      -
      - - - - + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Beginner's Guide

      + +
      + +

      +

      Beginner's Guide

      +


      +


      +

      This part of the documentation is presented in the form of a textbook on TASing.

      +

      It explains the practice of using Taseditor and describes the mechanism of conventional TASing methods.

      +

      The course will be useful both to people who wish to learn TASing and to already experienced TASers who are open to new trends and wish to improve their knowledge.

      +


      +


      +

      Introduction

      +

      General overview of TAS Editor's goals and features

      +


      +

      Program Interface

      +

      Learning the fundamentals of the program usage

      +


      +

      TASing Process

      +

      The author's vision of the competent working process

      +


      +

      TASing Methodology

      +

      Dissection of the Input improvement methods

      +


      +

      Program customization

      +

      Detailed review of all settings

      +


      +

      Advanced Features

      +

      Describing the additional possibilities

      +


      +


      +


      +


      +


      +

      +

      Created with the Personal Edition of HelpNDoc: Easy to use tool to create HTML Help files and Help web sites

      + +
      + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/taseditor/Controls.html b/web/help/taseditor/Controls.html index 681a69c0..65e14d01 100644 --- a/web/help/taseditor/Controls.html +++ b/web/help/taseditor/Controls.html @@ -1,501 +1,680 @@ - - + + + + + - Controls - - - - - - - - - - + + + + + + + + Controls + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Controls

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - -

      -

      Controls

      -


      -


      -

      Taseditor is controlled by mouse and keyboard.

      -

      Every operation can be done in several alternative ways (via menu, hotkey or GUI element).

      -

      Any action can be done using mouse, but some are faster to do with keyboard. The Manual assumes that one hand of user is holding the mouse and other hand is placed on a side of the keyboard, occasionally holding Shift/Ctrl/Alt or pressing a key combination.

      -

      Some actions (e.g. switching the "Follow cursor") can be done by mouse only.

      -


      -
      -

      -

      -

      Mouse controls

      -


      - -


      -

      -

      -

      Pointing with mouse

      -


      -

      A. Displaying Bookmarks screenshots and descriptions

      -

      Hover mouse cursor over the right half of Bookmarks List to see the game screenshot of the bookmarked frame in the movie branch you're pointing at. Optionally there can be a description of the branch under the screenshot.

      -


      -

      B. Displaying information of the Bookmark

      -

      Hover mouse cursor over an icon of any Bookmark in the Branches Tree to see the information about the Bookmark (real time of creation, bookmarked frame, full timeline, screenshot and description). When you point at a Bookmark that doesn't belong to the timeline of current movie branch, the mouse cursor changes to "arrow with question mark".

      -


      -

      C. Illuminating button symbols in the Piano Roll Header

      -

      Hover mouse cursor over a button symbol in the Piano Roll Header to see if you can change the movie by clicking this symbol. When some rows of Piano Roll are selected, symbols in the Header will illuminate on mouse hover.

      -


      -

      -

      -

      Left mouse button

      -


      -

      The main button.

      -


      -

      A. Standard Windows actions

      -

      Most of GUI elements of TAS Editor window are controlled the same way as in other Windows applications.

      -
        -
      • press a button by left-click (also works with the progressbar, "Bookmarks/Branches" caption and "Marker #" labels) – fires on button press
      • -
      • check/uncheck checkboxes and radiobuttons – fires on button release
      • -
      • open the window menu, choose menu item, set/remove ticks from menu items
      • -
      • scroll Piano Roll or History Log using scrollbars
      • -
      • move or resize TAS Editor window
      • -
      -


      -

      B. Moving the Playback cursor

      -

      Click on any row in the "Icons" column of the Piano Roll to send the Playback cursor to the frame pointed. If you hold the left mouse button, you can drag the Playback cursor up and down. This way you can also move the Playback cursor to frames outside the currently visible area of the movie – drag the cursor below or above the Piano Roll, the farther you lead the mouse, the faster will be scrolling and Playback rewinding.

      -


      -

      C. Selecting rows in the Piano Roll

      -

      Click on a frame number in the "Frame#" column of the Piano Roll to select this frame and remove selection from other frames (if there was any selection before). If you hold the left mouse button, you can stretch the selection by moving mouse up or down.

      -

      If you need to append new selection to the already existing selection, hold Ctrl while clicking on a frame number. This way you can select several non-overlapping segments. Also this way you can remove some parts of existing Selection, by holding Ctrl while clicking on a selected frame.

      -

      If you hold Shift instead of Ctrl, the click will select a region of frames starting from the beginning of previous Selection.

      -

      If you hold Alt, the click will select rows using current Pattern.

      -


      -

      D. Setting/unsetting Input in the Piano Roll

      -

      Point mouse cursor at needed cell of Input (find crossing point of the needed frame row and the needed button column) and press left mouse button. The Input in this cell changes at the moment you press the button. Empty cell will become occupied and vice versa.

      -

      The row containing this cell will also become selected, and other rows of the Piano Roll will become unselected. This feature ensures that Selection cursor always appears in the context of Input editing.

      -

      If you hold the left mouse button, you can draw or erase Input in other cells of the Piano Roll by moving mouse cursor over them. Drawing starts when you click on an empty cell, erasing starts by clicking on an occupied cell.

      -

      If you hold Shift while clicking on a cell, the Input change will apply to all frames from the Selection cursor to the row containing the cell.

      -

      If you hold Alt instead of Shift. the click will set Input (from the Selection cursor to the row containing the cell) using current Pattern.

      -


      -

      E. Setting/unsetting Input using the Header of the Piano Roll

      -

      Click on a button symbol in the Piano Roll Header to change Input of this button in selected frames. If no frames are selected, nothing will happen. If in some of the selected frames the button in not set, your click will set the button in all selected frames, otherwise the click will unset the button in all selected frames.

      -

      If you hold Alt while clicking on a button symbol, the click will set the button in selected frames using current Pattern.

      -

      If you click on the "Frame#" label, the click will apply to Markers instead of Input.

      -


      -

      F. Creating and moving Markers

      -

      Double-click on a frame number in the Piano Roll to set a Marker to this frame. If you hold the left mouse button, you can drag the Marker freely. Release the button to leave the Marker at the frame number it was held over. This way you can move Markers from place to place. If you release the Marker over Input columns, the dragging will be cancelled, and the Marker will return to the frame it was picked from. If you release the Marker over another Marker, those two Markers will switch places.

      -

      If you release the Marker outside the Piano Roll, this Marker will be dumped. Thus, to remove a Marker, double-click on it and drag it somewhere outside TAS Editor window.

      -


      -

      G. Entering/exiting Note editing mode

      -

      Click on the upper or the lower edit field to start editing Note text displayed in this field at the moment.

      -

      To finish editing (and save changes) click on anything outside the edit field.

      -


      -

      H. Controlling the Bookmarks List

      -

      Click on a frame number in the Bookmarks List (on the left side of the list) to send the Playback cursor to the bookmarked frame.

      -

      Click on a timestamp in the Bookmarks List (on the right side of the list) to restore movie state saved into the Bookmark and send the Playback cursor to the bookmarked frame.

      -

      Those operations fire on the button release.

      -


      -

      I. Controlling the Branches Tree

      -

      Click on icon of a Bookmark to send the Playback cursor to the bookmarked frame.

      -

      Double-click on icon of a Bookmark to restore movie state saved into the Bookmark and send the Playback cursor to the bookmarked frame.

      -

      Those operations fire on the button press.

      -


      -

      J. Controlling the History Log

      -

      Click on any row of the History Log to restore movie state to the point of time registered in the Log record.

      -


      -

      -

      -

      Right mouse button

      -


      -

      Auxiliary button.

      -


      -

      A. Moving the Playback cursor with mouse wheel

      -

      Hold the right button and roll the mouse wheel up or down to move the Playback cursor respectively.

      -

      The mouse cursor can be anywhere over the TAS Editor window or emulator main window.

      -


      -

      B. Scrolling the Piano Roll

      -

      Place mouse cursor over the Piano Roll, hold right button and move mouse cursor anywhere outside the Piano Roll to scroll visible area to that side. This is especially useful for horizontal scrolling, because using scrollbar would be too slow.

      -


      -

      C. Setting a Bookmark

      -

      Right-click on a row of the Bookmarks List to set the Bookmark to the frame where the Playback cursor currently is.

      -

      Alternatively, right-click on icon of a Bookmark in the Branches Tree to set the Bookmark to the frame where the Playback cursor currently is.

      -

      Those operations fire on the button release.

      -


      -

      D. Context menu

      -

      Right-click on a frame number of any selected frame in the Piano Roll to bring the context menu containing the following items:

      -
        -
      • Set Markers
      • -
      • Remove Markers
      • -
      • Deselect
      • -
      • Select between Markers
      • -
      • Ungreenzone
      • -
      • Clear
      • -
      • Delete
      • -
      • Insert
      • -
      • Insert # of Frames
      • -
      • Clone
      • -
      • Truncate movie
      • -
      -


      -

      Scrollbars and Note editing fields also have their own context menus.

      -


      -

      -

      -

      Middle mouse button

      -


      -

      The middle mouse button serves one major role – to pause and unpause emulator, no matter where mouse cursor is  The button fires on button press.

      -


      -

      When the emulator is paused, pressing the middle mouse button will unpause it (same was as pressing Pause hotkey). Moreover, if there is the green arrow outside the Greenzone in the Piano Roll, the middle-click will launch seeking to the frame of the green arrow (same way as pressing Restore Playback hotkey).

      -

      If you hold Shift while mid-clicking, this will launch seeking to the nearest Marker.

      -

      If you hold Ctrl while mid-clicking, this will either launch seeking to the Selection cursor (if it's below the Playback cursor) or re-watch the movie segment starting from the Selection cursor (if it's above the Playback cursor).

      -


      -

      When the emulator is unpaused, pressing the middle mouse button will pause it (same way as pressing Pause hotkey).

      -


      -

      Usually the middle mouse button is the mouse wheel.

      -


      -

      -

      -

      Mouse wheel

      -


      -

      The wheel can be rolled up and down with different speed. When you need precision, roll the wheel slowly. When you need speed, roll the wheel quickly.

      -


      -

      A. Scrolling the Piano Roll or the History Log

      -

      When mouse cursor is over the History Log, roll the mouse wheel to scroll visible area of the History Log.

      -

      When mouse cursor is anywhere else, roll the mouse wheel to scroll visible area of the Piano Roll.

      -


      -

      B. Moving the Playback cursor

      -

      Hold right mouse button and roll the mouse wheel up or down to move the Playback cursor respectively.

      -

      If you want to always see the Playback cursor position in the Piano Roll, check the "Follow cursor" checkbox in the Playback section of TAS Editor window.

      -


      -

      C. Jumping on Markers

      -

      This is similar to pressing << and >> buttons or using Ctrl/Shift + Page Up/Page Down hotkeys.

      -

      Hold Shift and roll the wheel to make jumps with the Playback cursor. The Piano Roll will follow it if the "Follow cursor" checkbox is checked.

      -

      Hold Ctrl and roll the wheel to make jumps with the Selection cursor. The Piano Roll will follow it automatically.

      -


      -

      D. Crossing gaps

      -


      -

      Point mouse cursor to any member of a long column of buttonpresses or to an empty cell among other empty cells in its neighborhood, then hold the Alt key and roll the wheel up or down to scroll the Piano Roll in such a manner that mouse cursor immediately points at the upper end or the lower end of the column / emptiness.

      -

      This allows you to quickly navigate among long sequences of Input.

      -

      The same approach can be used to find previous/next Markers (when mouse cursor is over the column with frame numbers) and Bookmarks (when it's over the icons column).

      -


      -
      -

      -

      -

      Keyboard controls

      -


      -

      -


      - -


      -

      -

      -

      Modifiers (Shift, Ctrl, Alt)

      -


      -

      When you hold one of these keys, the functions of left mouse button and mouse wheel are modified.

      -


      -
        -
      • Shift is responsible for the Playback cursor navigation and for selecting whole region of frames.
      • -
      • Ctrl is responsible for the Selection cursor navigation and for appending frames to current Selection.
      • -
      • Alt is responsible for Patterns and for crossing gaps using mouse wheel.
      • -
      -


      -

      If you tap the Shift key twice in a row, the Piano Roll will automatically scroll to the Playback cursor.

      -

      If you tap the Ctrl key twice in a row, the Piano Roll will automatically scroll to the Selection cursor.

      -


      -

      When you're drawing/erasing Input, hold Shift key to remove the "single-column" confinement.

      -


      -

      -

      -

      Accelerator hotkeys

      -


      -

      These are key combinations typical for many Windows applications. You cannot redefine those combinations. In this documentation they are highlighted with red color.

      -


      -

      -


      -

      Ctrl + S = save project to disk

      -


      -

      Ctrl + Z = undo (step back in History Log)

      -

      Ctrl + Y = redo (step forward in History Log)

      -


      -

      Ctrl + Q = restore previous Selection (Selection undo)

      -

      Ctrl + W = restore next Selection (Selection redo)

      -

      Ctrl + A = select all frames between two Markers surrounding the Selection cursor

      -

      Ctrl + B = reselect frames that contain Input that was copied to the Clipboard

      -


      -

      Ctrl + C = copy selected Input to the Clipboard (Copy)

      -

      Ctrl + X = copy selected Input to the Clipboard and then clear selected frames (Cut)

      -

      Ctrl + V = paste Input from the Clipboard to Selection cursor (Paste)

      -

      Ctrl + Shift + V = insert Input from the Clipboard to the Selection cursor (PasteInsert)

      -


      -

      Delete = clear selected frames

      -

      Ctrl + Delete = remove selected frames from the movie

      -

      Insert = insert given number of blank frames before the Selection cursor

      -

      Ctrl + Insert = clone selected frames

      -

      Ctrl + Shift + Insert = insert blank frames before selected frames

      -


      -

      Ctrl + F = bring the "Find Note" dialog

      -


      -

      Ctrl + PageUp / Ctrl + PageDown = jump on Markers with the Selection cursor

      -

      Ctrl + Home / Ctrl + End = move current Selection to the beginning / to the end of the movie

      -

      Ctrl + Up / Ctrl + Down = transpose current Selection 1 frame up / down

      -

      Ctrl + Right / Ctrl + Left = scroll the Piano Roll right / left

      -


      -

      Shift + PageUp / Shift + PageDown = jump on Markers with the Playback cursor

      -

      Shift + Home / Shift + End = send the Playback cursor to the beginning / to the end of the movie

      -

      Shift + Up / Shift + Down = move the Playback cursor 1 frame up / down

      -

      Shift + Right / Shift + Left = scroll the Piano Roll right / left

      -


      -

      PageUp / PageDown = scroll the Piano Roll up / down

      -

      Home / End = scroll the Piano Roll to the beginning / to the end of the movie

      -


      -

      -

      -

      FCEUX hotkeys

      -


      -

      Emulator allows to map keyboard keys to different functions, see the Program Customization chapter. Keys that are already mapped by default are highlighted by light-blue color in this documentation.

      -


      -

      -


      -

      Ctrl + F1 = reload last project

      -


      -

      Pause = pause/unpause emulator

      -

      Esc = cancel seeking

      -

      Spacebar = restore Playback cursor position (launch seeking to the green arrow)

      -

      Ctrl + Spacebar = toggle "Auto-restore last position" checkbox

      -

      \ (backslash) = Frame Advance (emulate 1 frame)

      -

      Backspace = Frame Rewind (move Playback cursor 1 frame up)

      -

      Shift + R = play movie from the beginning

      -


      -

      - (white "minus") = decrease emulation speed

      -

      = (white "plus") = increase emulation speed

      -

      Tab = Turbo speed (applies as long as the key is being held)

      -


      -

      F1-F10 = load movie branch from the respective Bookmark slot (1-10)

      -

      1-0 = jump to the frame of the Bookmark (1-10)

      -

      Shift + F1-F10 = set Bookmark (1-10)

      -

      I = set currently selected Bookmark

      -

      P = load movie branch from currently selected Bookmark

      -


      -

      M = show/hide rerecord counter

      -

      , (comma) = switch Input display

      -

      . (dot) = show/hide frame counter

      -

      / (slash) = show/hide lag counter

      -


      -

      Shift + L = reload current Lua script

      -


      -

      Q = toggle Recording mode

      -

      W = switch current multitracking mode

      -

      Ctrl + R = invoke Reset command

      -


      -

      Full list of FCEUX hotkeys that can be used when Taseditor is engaged:

      -


      -
        -
      • Power
      • -
      • Reset
      • -
      • Pause
      • -
      • Frame Advance
      • -
      • Screenshot
      • -
      • Exit
      • -
      • Slowest Speed
      • -
      • Speed Down
      • -
      • Normal Speed
      • -
      • Speed Up
      • -
      • Turbo
      • -
      • Turbo Toggle
      • -
      • Savestate Slot 0
      • -
      • Savestate Slot 1
      • -
      • Savestate Slot 2
      • -
      • Savestate Slot 3
      • -
      • Savestate Slot 4
      • -
      • Savestate Slot 5
      • -
      • Savestate Slot 6
      • -
      • Savestate Slot 7
      • -
      • Savestate Slot 8
      • -
      • Savestate Slot 9
      • -
      • Next Savestate Slot
      • -
      • Previous Savestate Slot
      • -
      • Save State
      • -
      • Save State to Slot 0
      • -
      • Save State to Slot 1
      • -
      • Save State to Slot 2
      • -
      • Save State to Slot 3
      • -
      • Save State to Slot 4
      • -
      • Save State to Slot 5
      • -
      • Save State to Slot 6
      • -
      • Save State to Slot 7
      • -
      • Save State to Slot 8
      • -
      • Save State to Slot 9
      • -
      • Load State
      • -
      • Load State from Slot 0
      • -
      • Load State from Slot 1
      • -
      • Load State from Slot 2
      • -
      • Load State from Slot 3
      • -
      • Load State from Slot 4
      • -
      • Load State from Slot 5
      • -
      • Load State from Slot 6
      • -
      • Load State from Slot 7
      • -
      • Load State from Slot 8
      • -
      • Load State from Slot 9
      • -
      • Play Movie From Beginning
      • -
      • Toggle Read-Only
      • -
      • Toggle Frame Display
      • -
      • Toggle Input Display
      • -
      • Toggle Status Icon
      • -
      • Reload current Lua script
      • -
      • Sound Mute Toggle
      • -
      • Sound Volume Up
      • -
      • Sound Volume Down
      • -
      • Sound Volume Normal
      • -
      • Record AVI As...
      • -
      • Stop AVI
      • -
      • Eject or Insert FDS Disk
      • -
      • Switch FDS Disk Side
      • -
      • Insert Coin
      • -
      • Use Input Preset 1
      • -
      • Use Input Preset 2
      • -
      • Use Input Preset 3
      • -
      • Toggle Background Display
      • -
      • Toggle Object Display
      • -
      • Lag Counter Toggle
      • -
      • Open TAS Editor
      • -
      • Open Memory Watch
      • -
      • Open Cheats
      • -
      • Open Debugger
      • -
      • Open Hex Editor
      • -
      • Open PPU Viewer
      • -
      • Open Name Table Viewer
      • -
      • Open Trace Logger
      • -
      • Open Code/Data Logger
      • -
      • Frame Adv.-Skip Lag
      • -
      • Reload ROM or TAS Editor Project
      • -
      • Toggle Movie Subtitles
      • -
      • Open Ram Watch
      • -
      • Open Ram Search
      • -
      • Toggle Rerecord Display
      • -
      • Frame Rewind
      • -
      • Restore Playback
      • -
      • Cancel Seeking
      • -
      • Switch Auto-restore last position
      • -
      • Switch current Multitracking mode
      • -
      • Run Manual Lua function
      • -
      • Toggle FPS Display
      • -
      -


      -

      Other FCEUX hotkeys will not work when Taseditor is running, for more details see Mistake-proofing.

      -


      -

      -

      -

      Virtual gamepad

      -


      -

      Emulator also allows to map keyboard keys to buttons of emulated console. You can use these keys for Input Recording and for Changing Input in Selection chapter.

      -

      By default, the following keys are mapped to the Player 1 buttons:

      -

      DB

      -

      FA

      -

      EnterStart

      -

      SSelect

      -

      Keypad upUp

      -

      Keypad leftLeft

      -

      Keypad downDown

      -

      Keypad rightRight

      -


      -

      When you need to input hardware commands, use FCEUX menu or hotkeys:

      -
        -
      • NES -> Reset or "Reset" hotkey (Ctrl + R by default) – to invoke the "Reset" command
      • -
      • NES -> Power or "Power" hotkey – to invoke the "Power switch" command (not used in practical TASing)
      • -
      • NES -> Eject/Insert Disk or "Eject or Insert FDS Disk" hotkey – to invoke the disk command (only useful for a Famicom Disk System game)
      • -
      • NES -> Switch Disk Side or "Switch FDS Disk Side" hotkey – to invoke the disk command (only useful for a Famicom Disk System game)
      • -
      • NES -> Insert Coin or "Insert Coin" hotkey – to invoke the arcade machine command (only useful for a VS System game)
      • -
      -


      -

      These commands work only when Recording mode is on. After invoking a command you need to advance at least 1 frame to actually activate the command and insert it into the movie.

      -

      Since in TAS Editor 1.0 the Piano Roll doesn't have columns for displaying hardware commands (they are rarely used), it's recommended to set Markers to frames where a command was inserted.

      -


      -
      -

      -

      -

      Controls in Note editing mode

      -


      -


      -

      When you enter Note editing mode, the keyboard is used for typing the text.

      -


      -

      1. Accelerator hotkeys do not work.

      -

      Ctrl + A – select all text of the Note

      -

      Ctrl + Z – undo/redo the last change in the text

      -

      Ctrl + X, Ctrl + C, Ctrl + V – text copy/cut/paste

      -


      -

      2. FCEUX hotkeys do not work.

      -

      Backspacedelete previous symbol

      -

      Esc – exit Note editing mode without saving any changes

      -

      Tab – toggle between upper and lower Note editing field

      -


      -

      3. Virtual gamepad keys do not work. Note: they will work if you check the Config -> Enable -> Background Input in FCEUX menu, so it's not recommended to enable the feature.

      -


      -

      4. Mouse controls are the same as usual.  Any click outside the text edit field (except for mid-clicks) will exit Note editing mode and save text changes. Also, if the Playback cursor or the Selection cursor move away from the Marker while you're editing its Note, the text changes will be saved and you'll begin editing another Marker's Note. So it's recommended to only edit Notes when the emulator is paused.

      -


      -


      -


      -


      -


      -

      -

      Created with the Personal Edition of HelpNDoc: Full-featured Kindle eBooks generator

      -
      - - - - + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Controls

      + +
      + +

      +

      Controls

      +


      +


      +

      Taseditor is controlled by mouse and keyboard.

      +

      Every operation can be done in several alternative ways (via menu, hotkey or GUI element).

      +

      Any action can be done using mouse, but some are faster to do with keyboard. The Manual assumes that one hand of user is holding the mouse and other hand is placed on a side of the keyboard, occasionally holding Shift/Ctrl/Alt or pressing a key combination.

      +

      Some actions (e.g. switching the "Follow cursor") can be done by mouse only.

      +


      +
      +


      +

      Mouse controls

      +


      + +


      +


      +

      Pointing with mouse

      +


      +

      A. Displaying Bookmarks screenshots and descriptions

      +

      Hover mouse cursor over the right half of Bookmarks List to see the game screenshot of the bookmarked frame in the movie branch you're pointing at. Optionally there can be a description of the branch under the screenshot.

      +


      +

      B. Displaying information of the Bookmark

      +

      Hover mouse cursor over an icon of any Bookmark in the Branches Tree to see the information about the Bookmark (real time of creation, bookmarked frame, full timeline, screenshot and description). When you point at a Bookmark that doesn't belong to the timeline of current movie branch, the mouse cursor changes to "arrow with question mark".

      +


      +

      C. Illuminating button symbols in the Piano Roll Header

      +

      Hover mouse cursor over a button symbol in the Piano Roll Header to see if you can change the movie by clicking this symbol. When some rows of Piano Roll are selected, symbols in the Header will illuminate on mouse hover.

      +


      +


      +

      Left mouse button

      +


      +

      The main button.

      +


      +

      A. Standard Windows actions

      +

      Most of GUI elements of TAS Editor window are controlled the same way as in other Windows applications.

      +
        +
      • press a button by left-click (also works with the progressbar, "Bookmarks/Branches" caption and "Marker #" labels) – fires on button press
      • +
      • check/uncheck checkboxes and radiobuttons – fires on button release
      • +
      • open the window menu, choose menu item, set/remove ticks from menu items
      • +
      • scroll Piano Roll or History Log using scrollbars
      • +
      • move or resize TAS Editor window
      • +
      +


      +

      B. Moving the Playback cursor

      +

      Click on any row in the "Icons" column of the Piano Roll to send the Playback cursor to the frame pointed. If you hold the left mouse button, you can drag the Playback cursor up and down. This way you can also move the Playback cursor to frames outside the currently visible area of the movie – drag the cursor below or above the Piano Roll, the farther you lead the mouse, the faster will be scrolling and Playback rewinding.

      +


      +

      C. Selecting rows in the Piano Roll

      +

      Click on a frame number in the "Frame#" column of the Piano Roll to select this frame and remove selection from other frames (if there was any selection before). If you hold the left mouse button, you can stretch the selection by moving mouse up or down.

      +

      If you need to append new selection to the already existing selection, hold Ctrl while clicking on a frame number. This way you can select several non-overlapping segments. Also this way you can remove some parts of existing Selection, by holding Ctrl while clicking on a selected frame.

      +

      If you hold Shift instead of Ctrl, the click will select a region of frames starting from the beginning of previous Selection.

      +

      If you hold Alt, the click will select rows using current Pattern.

      +


      +

      D. Setting/unsetting Input in the Piano Roll

      +

      Point mouse cursor at needed cell of Input (find crossing point of the needed frame row and the needed button column) and press left mouse button. The Input in this cell changes at the moment you press the button. Empty cell will become occupied and vice versa.

      +

      The row containing this cell will also become selected, and other rows of the Piano Roll will become unselected. This feature ensures that Selection cursor always appears in the context of Input editing.

      +

      If you hold the left mouse button, you can draw or erase Input in other cells of the Piano Roll by moving mouse cursor over them. Drawing starts when you click on an empty cell, erasing starts by clicking on an occupied cell.

      +

      If you hold Shift while clicking on a cell, the Input change will apply to all frames from the Selection cursor to the row containing the cell.

      +

      If you hold Alt instead of Shift. the click will set Input (from the Selection cursor to the row containing the cell) using current Pattern.

      +


      +

      E. Setting/unsetting Input using the Header of the Piano Roll

      +

      Click on a button symbol in the Piano Roll Header to change Input of this button in selected frames. If no frames are selected, nothing will happen. If in some of the selected frames the button in not set, your click will set the button in all selected frames, otherwise the click will unset the button in all selected frames.

      +

      If you hold Alt while clicking on a button symbol, the click will set the button in selected frames using current Pattern.

      +

      If you click on the "Frame#" label, the click will apply to Markers instead of Input.

      +


      +

      F. Creating and moving Markers

      +

      Double-click on a frame number in the Piano Roll to set a Marker to this frame. If you hold the left mouse button, you can drag the Marker freely. Release the button to leave the Marker at the frame number it was held over. This way you can move Markers from place to place. If you release the Marker over Input columns, the dragging will be cancelled, and the Marker will return to the frame it was picked from. If you release the Marker over another Marker, those two Markers will switch places.

      +

      If you release the Marker outside the Piano Roll, this Marker will be dumped. Thus, to remove a Marker, double-click on it and drag it somewhere outside TAS Editor window.

      +


      +

      G. Entering/exiting Note editing mode

      +

      Click on the upper or the lower edit field to start editing Note text displayed in this field at the moment.

      +

      To finish editing (and save changes) click on anything outside the edit field.

      +


      +

      H. Controlling the Bookmarks List

      +

      Click on a frame number in the Bookmarks List (on the left side of the list) to send the Playback cursor to the bookmarked frame.

      +

      Click on a timestamp in the Bookmarks List (on the right side of the list) to restore movie state saved into the Bookmark and send the Playback cursor to the bookmarked frame.

      +

      Those operations fire on the button release.

      +


      +

      I. Controlling the Branches Tree

      +

      Click on icon of a Bookmark to send the Playback cursor to the bookmarked frame.

      +

      Double-click on icon of a Bookmark to restore movie state saved into the Bookmark and send the Playback cursor to the bookmarked frame.

      +

      Those operations fire on the button press.

      +


      +

      J. Controlling the History Log

      +

      Click on any row of the History Log to restore movie state to the point of time registered in the Log record.

      +


      +


      +

      Right mouse button

      +


      +

      Auxiliary button.

      +


      +

      A. Moving the Playback cursor with mouse wheel

      +

      Hold the right button and roll the mouse wheel up or down to move the Playback cursor respectively.

      +

      The mouse cursor can be anywhere over the TAS Editor window or emulator main window.

      +


      +

      B. Scrolling the Piano Roll

      +

      Place mouse cursor over the Piano Roll, hold right button and move mouse cursor anywhere outside the Piano Roll to scroll visible area to that side. This is especially useful for horizontal scrolling, because using scrollbar would be too slow.

      +


      +

      C. Setting a Bookmark

      +

      Right-click on a row of the Bookmarks List to set the Bookmark to the frame where the Playback cursor currently is.

      +

      Alternatively, right-click on icon of a Bookmark in the Branches Tree to set the Bookmark to the frame where the Playback cursor currently is.

      +

      Those operations fire on the button release.

      +


      +

      D. Context menu

      +

      Right-click on a frame number of any selected frame in the Piano Roll to bring the context menu containing the following items:

      +
        +
      • Set Markers
      • +
      • Remove Markers
      • +
      • Deselect
      • +
      • Select between Markers
      • +
      • Ungreenzone
      • +
      • Clear
      • +
      • Delete
      • +
      • Insert
      • +
      • Insert # of Frames
      • +
      • Clone
      • +
      • Truncate movie
      • +
      +


      +

      Scrollbars and Note editing fields also have their own context menus.

      +


      +


      +

      Middle mouse button

      +


      +

      The middle mouse button serves one major role – to pause and unpause emulator, no matter where mouse cursor is  The button fires on button press.

      +


      +

      When the emulator is paused, pressing the middle mouse button will unpause it (same was as pressing Pause hotkey). Moreover, if there is the green arrow outside the Greenzone in the Piano Roll, the middle-click will launch seeking to the frame of the green arrow (same way as pressing Restore Playback hotkey).

      +

      If you hold Shift while mid-clicking, this will launch seeking to the nearest Marker.

      +

      If you hold Ctrl while mid-clicking, this will either launch seeking to the Selection cursor (if it's below the Playback cursor) or re-watch the movie segment starting from the Selection cursor (if it's above the Playback cursor).

      +


      +

      When the emulator is unpaused, pressing the middle mouse button will pause it (same way as pressing Pause hotkey).

      +


      +

      Usually the middle mouse button is the mouse wheel.

      +


      +


      +

      Mouse wheel

      +


      +

      The wheel can be rolled up and down with different speed. When you need precision, roll the wheel slowly. When you need speed, roll the wheel quickly.

      +


      +

      A. Scrolling the Piano Roll or the History Log

      +

      When mouse cursor is over the History Log, roll the mouse wheel to scroll visible area of the History Log.

      +

      When mouse cursor is anywhere else, roll the mouse wheel to scroll visible area of the Piano Roll.

      +


      +

      B. Moving the Playback cursor

      +

      Hold right mouse button and roll the mouse wheel up or down to move the Playback cursor respectively.

      +

      If you want to always see the Playback cursor position in the Piano Roll, check the "Follow cursor" checkbox in the Playback section of TAS Editor window.

      +


      +

      C. Jumping on Markers

      +

      This is similar to pressing << and >> buttons or using Ctrl/Shift + Page Up/Page Down hotkeys.

      +

      Hold Shift and roll the wheel to make jumps with the Playback cursor. The Piano Roll will follow it if the "Follow cursor" checkbox is checked.

      +

      Hold Ctrl and roll the wheel to make jumps with the Selection cursor. The Piano Roll will follow it automatically.

      +


      +

      D. Crossing gaps

      +


      +

      Point mouse cursor to any member of a long column of buttonpresses or to an empty cell among other empty cells in its neighborhood, then hold the Alt key and roll the wheel up or down to scroll the Piano Roll in such a manner that mouse cursor immediately points at the upper end or the lower end of the column / emptiness.

      +

      This allows you to quickly navigate among long sequences of Input.

      +

      The same approach can be used to find previous/next Markers (when mouse cursor is over the column with frame numbers) and Bookmarks (when it's over the icons column).

      +


      +
      +


      +

      Keyboard controls

      +


      +

      +


      + +


      +


      +

      Modifiers (Shift, Ctrl, Alt)

      +


      +

      When you hold one of these keys, the functions of left mouse button and mouse wheel are modified.

      +


      +
        +
      • Shift is responsible for the Playback cursor navigation and for selecting whole region of frames.
      • +
      • Ctrl is responsible for the Selection cursor navigation and for appending frames to current Selection.
      • +
      • Alt is responsible for Patterns and for crossing gaps using mouse wheel.
      • +
      +


      +

      If you tap the Shift key twice in a row, the Piano Roll will automatically scroll to the Playback cursor.

      +

      If you tap the Ctrl key twice in a row, the Piano Roll will automatically scroll to the Selection cursor.

      +


      +

      When you're drawing/erasing Input, hold Shift key to remove the "single-column" confinement.

      +


      +


      +

      Accelerator hotkeys

      +


      +

      These are key combinations typical for many Windows applications. You cannot redefine those combinations. In this documentation they are highlighted with red color.

      +


      +

      +


      +

      Ctrl + S = save project to disk

      +


      +

      Ctrl + Z = undo (step back in History Log)

      +

      Ctrl + Y = redo (step forward in History Log)

      +


      +

      Ctrl + Q = restore previous Selection (Selection undo)

      +

      Ctrl + W = restore next Selection (Selection redo)

      +

      Ctrl + A = select all frames between two Markers surrounding the Selection cursor

      +

      Ctrl + B = reselect frames that contain Input that was copied to the Clipboard

      +


      +

      Ctrl + C = copy selected Input to the Clipboard (Copy)

      +

      Ctrl + X = copy selected Input to the Clipboard and then clear selected frames (Cut)

      +

      Ctrl + V = paste Input from the Clipboard to Selection cursor (Paste)

      +

      Ctrl + Shift + V = insert Input from the Clipboard to the Selection cursor (PasteInsert)

      +


      +

      Delete = clear selected frames

      +

      Ctrl + Delete = remove selected frames from the movie

      +

      Insert = insert given number of blank frames before the Selection cursor

      +

      Ctrl + Insert = clone selected frames

      +

      Ctrl + Shift + Insert = insert blank frames before selected frames

      +


      +

      Ctrl + F = bring the "Find Note" dialog

      +


      +

      Ctrl + PageUp / Ctrl + PageDown = jump on Markers with the Selection cursor

      +

      Ctrl + Home / Ctrl + End = move current Selection to the beginning / to the end of the movie

      +

      Ctrl + Up / Ctrl + Down = transpose current Selection 1 frame up / down

      +

      Ctrl + Right / Ctrl + Left = scroll the Piano Roll right / left

      +


      +

      Shift + PageUp / Shift + PageDown = jump on Markers with the Playback cursor

      +

      Shift + Home / Shift + End = send the Playback cursor to the beginning / to the end of the movie

      +

      Shift + Up / Shift + Down = move the Playback cursor 1 frame up / down

      +

      Shift + Right / Shift + Left = scroll the Piano Roll right / left

      +


      +

      PageUp / PageDown = scroll the Piano Roll up / down

      +

      Home / End = scroll the Piano Roll to the beginning / to the end of the movie

      +


      +


      +

      FCEUX hotkeys

      +


      +

      Emulator allows to map keyboard keys to different functions, see the Program Customization chapter. Keys that are already mapped by default are highlighted by light-blue color in this documentation.

      +


      +

      +


      +

      Ctrl + F1 = reload last project

      +


      +

      Pause = pause/unpause emulator

      +

      Esc = cancel seeking

      +

      Spacebar = restore Playback cursor position (launch seeking to the green arrow)

      +

      Ctrl + Spacebar = toggle "Auto-restore last position" checkbox

      +

      \ (backslash) = Frame Advance (emulate 1 frame)

      +

      Backspace = Frame Rewind (move Playback cursor 1 frame up)

      +

      Shift + R = play movie from the beginning

      +


      +

      - (white "minus") = decrease emulation speed

      +

      = (white "plus") = increase emulation speed

      +

      Tab = Turbo speed (applies as long as the key is being held)

      +


      +

      F1-F10 = load movie branch from the respective Bookmark slot (1-10)

      +

      1-0 = jump to the frame of the Bookmark (1-10)

      +

      Shift + F1-F10 = set Bookmark (1-10)

      +

      I = set currently selected Bookmark

      +

      P = load movie branch from currently selected Bookmark

      +


      +

      M = show/hide rerecord counter

      +

      , (comma) = switch Input display

      +

      . (dot) = show/hide frame counter

      +

      / (slash) = show/hide lag counter

      +


      +

      Shift + L = reload current Lua script

      +


      +

      Q = toggle Recording mode

      +

      W = switch current multitracking mode

      +

      Ctrl + R = invoke Reset command

      +


      +

      Full list of FCEUX hotkeys that can be used when Taseditor is engaged:

      +


      +
        +
      • Power
      • +
      • Reset
      • +
      • Pause
      • +
      • Frame Advance
      • +
      • Screenshot
      • +
      • Exit
      • +
      • Slowest Speed
      • +
      • Speed Down
      • +
      • Normal Speed
      • +
      • Speed Up
      • +
      • Turbo
      • +
      • Turbo Toggle
      • +
      • Savestate Slot 0
      • +
      • Savestate Slot 1
      • +
      • Savestate Slot 2
      • +
      • Savestate Slot 3
      • +
      • Savestate Slot 4
      • +
      • Savestate Slot 5
      • +
      • Savestate Slot 6
      • +
      • Savestate Slot 7
      • +
      • Savestate Slot 8
      • +
      • Savestate Slot 9
      • +
      • Next Savestate Slot
      • +
      • Previous Savestate Slot
      • +
      • Save State
      • +
      • Save State to Slot 0
      • +
      • Save State to Slot 1
      • +
      • Save State to Slot 2
      • +
      • Save State to Slot 3
      • +
      • Save State to Slot 4
      • +
      • Save State to Slot 5
      • +
      • Save State to Slot 6
      • +
      • Save State to Slot 7
      • +
      • Save State to Slot 8
      • +
      • Save State to Slot 9
      • +
      • Load State
      • +
      • Load State from Slot 0
      • +
      • Load State from Slot 1
      • +
      • Load State from Slot 2
      • +
      • Load State from Slot 3
      • +
      • Load State from Slot 4
      • +
      • Load State from Slot 5
      • +
      • Load State from Slot 6
      • +
      • Load State from Slot 7
      • +
      • Load State from Slot 8
      • +
      • Load State from Slot 9
      • +
      • Play Movie From Beginning
      • +
      • Toggle Read-Only
      • +
      • Toggle Frame Display
      • +
      • Toggle Input Display
      • +
      • Toggle Status Icon
      • +
      • Reload current Lua script
      • +
      • Sound Mute Toggle
      • +
      • Sound Volume Up
      • +
      • Sound Volume Down
      • +
      • Sound Volume Normal
      • +
      • Record AVI As...
      • +
      • Stop AVI
      • +
      • Eject or Insert FDS Disk
      • +
      • Switch FDS Disk Side
      • +
      • Insert Coin
      • +
      • Use Input Preset 1
      • +
      • Use Input Preset 2
      • +
      • Use Input Preset 3
      • +
      • Toggle Background Display
      • +
      • Toggle Object Display
      • +
      • Lag Counter Toggle
      • +
      • Open TAS Editor
      • +
      • Open Memory Watch
      • +
      • Open Cheats
      • +
      • Open Debugger
      • +
      • Open Hex Editor
      • +
      • Open PPU Viewer
      • +
      • Open Name Table Viewer
      • +
      • Open Trace Logger
      • +
      • Open Code/Data Logger
      • +
      • Frame Adv.-Skip Lag
      • +
      • Reload ROM or TAS Editor Project
      • +
      • Toggle Movie Subtitles
      • +
      • Open Ram Watch
      • +
      • Open Ram Search
      • +
      • Toggle Rerecord Display
      • +
      • Frame Rewind
      • +
      • Restore Playback
      • +
      • Cancel Seeking
      • +
      • Switch Auto-restore last position
      • +
      • Switch current Multitracking mode
      • +
      • Run Manual Lua function
      • +
      • Toggle FPS Display
      • +
      +


      +

      Other FCEUX hotkeys will not work when Taseditor is running, for more details see Mistake-proofing.

      +


      +


      +

      Virtual gamepad

      +


      +

      Emulator also allows to map keyboard keys to buttons of emulated console. You can use these keys for Input Recording and for Changing Input in Selection chapter.

      +

      By default, the following keys are mapped to the Player 1 buttons:

      +

      DB

      +

      FA

      +

      EnterStart

      +

      SSelect

      +

      Keypad upUp

      +

      Keypad leftLeft

      +

      Keypad downDown

      +

      Keypad rightRight

      +


      +

      When you need to input hardware commands, use FCEUX menu or hotkeys:

      +
        +
      • NES -> Reset or "Reset" hotkey (Ctrl + R by default) – to invoke the "Reset" command
      • +
      • NES -> Power or "Power" hotkey – to invoke the "Power switch" command (not used in practical TASing)
      • +
      • NES -> Eject/Insert Disk or "Eject or Insert FDS Disk" hotkey – to invoke the disk command (only useful for a Famicom Disk System game)
      • +
      • NES -> Switch Disk Side or "Switch FDS Disk Side" hotkey – to invoke the disk command (only useful for a Famicom Disk System game)
      • +
      • NES -> Insert Coin or "Insert Coin" hotkey – to invoke the arcade machine command (only useful for a VS System game)
      • +
      +


      +

      These commands work only when Recording mode is on. After invoking a command you need to advance at least 1 frame to actually activate the command and insert it into the movie.

      +

      Since in TAS Editor 1.0 the Piano Roll doesn't have columns for displaying hardware commands (they are rarely used), it's recommended to set Markers to frames where a command was inserted.

      +


      +
      +


      +

      Controls in Note editing mode

      +


      +


      +

      When you enter Note editing mode, the keyboard is used for typing the text.

      +


      +

      1. Accelerator hotkeys do not work.

      +

      Ctrl + A – select all text of the Note

      +

      Ctrl + Z – undo/redo the last change in the text

      +

      Ctrl + X, Ctrl + C, Ctrl + V – text copy/cut/paste

      +


      +

      2. FCEUX hotkeys do not work.

      +

      Backspacedelete previous symbol

      +

      Esc – exit Note editing mode without saving any changes

      +

      Tab – toggle between upper and lower Note editing field

      +


      +

      3. Virtual gamepad keys do not work. Note: they will work if you check the Config -> Enable -> Background Input in FCEUX menu, so it's not recommended to enable the feature.

      +


      +

      4. Mouse controls are the same as usual.  Any click outside the text edit field (except for mid-clicks) will exit Note editing mode and save text changes. Also, if the Playback cursor or the Selection cursor move away from the Marker while you're editing its Note, the text changes will be saved and you'll begin editing another Marker's Note. So it's recommended to only edit Notes when the emulator is paused.

      +


      +


      +


      +


      +


      +

      +

      Created with the Personal Edition of HelpNDoc: Free Kindle producer

      + +
      + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/taseditor/FAQ.html b/web/help/taseditor/FAQ.html index 6813b09d..8d660235 100644 --- a/web/help/taseditor/FAQ.html +++ b/web/help/taseditor/FAQ.html @@ -1,140 +1,331 @@ - - + + + + + - FAQ - - - - - - - - - - + + + + + + + + FAQ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      FAQ

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      FAQ

      + +
      +

      -

      FAQ

      +

      FAQ



      -

      If after reading the Manual you still have any questions on the topic, feel free to ask them at TASVideos forum.

      -


      -
      -


      -

      I think I've found a bug in the program, what should I do?

      -

      Post a message in the FCEUX subforum of TASVideos. Try to explain the issue precisely, to help author reproduce the situation. Attach a screenshot if you think it reflects the essence of the problem.

      -


      -

      Is it possible to use Taseditor with other emulators?

      -

      No. Even though the program code of Taseditor is mostly isolated from the emulator code, it is by no means a plug-in. So it's necessary to manually port its source code and modify it according to specifications of target platform.

      -


      -

      How can I TAS the traditional way, yet with Taseditor interface?

      -

      Basically, you can start traditional TASing right away, no additional settings are required. But if you must keep some old habits intact, you can fine-tune the program. Try the following options:

      -
        -
      • switch on the Config -> Old control scheme for Branching option
      • -
      • switch off the Config -> Branches restore entire Movie option
      • -
      • switch on the Config -> Combine consecutive Recordings/Draws option
      • -
      • switch off the Config -> Use Input keys for Column Set option
      • +

        If after reading the Manual you still have any questions on the topic, feel free to ask them at TASVideos forum.

        +


        +
        +


        +

        I think I've found a bug in the program, what should I do?

        +

        Post a message in the FCEUX subforum of TASVideos. Try to explain the issue precisely, to help author reproduce the situation. Attach a screenshot if you think it reflects the essence of the problem.

        +


        +

        Is it possible to use Taseditor with other emulators?

        +

        No. Even though the program code of Taseditor is mostly isolated from the emulator code, it is by no means a plug-in. So it's necessary to manually port its source code and modify it according to specifications of target platform.

        +


        +

        How can I TAS the traditional way, yet with Taseditor interface?

        +

        Basically, you can start traditional TASing right away, no additional settings are required. But if you must keep some old habits intact, you can fine-tune the program. Try the following options:

        + -

        Also, it's recommended to switch the Bookmarks List to the "Branches Tree" view.

        -


        -

        Why the right-click on the FCEUX window doesn't prompt the usual context menu?

        -

        It's done to facilitate the Playback cursor navigation with the mouse wheel.

        -

        Usually users move the mouse cursor in such a manner that it's in sight. Thus when TASer is watching the game events the cursor will often be inside the FCEUX window. Context menus would obstruct the view when you want to rewind the Playback by holding the right mouse button and rolling the mouse wheel. So, since there's no important items in the menu while TAS Editor is engaged, the menu was removed.

        -


        -

        Why the right-click on the Piano Roll sometimes prompts a context menu and sometimes doesn't?

        -

        Taseditor's context menu only appears when you right-click on the number of a selected frame. If you right-click on a frame that is not selected, or you right-click on the Input of a selected frame, the menu won't appear.

        -

        It's done to facilitate the Piano Roll scrolling by right-clicking and dragging.

        -

        Generally, it's recommended to use keyboard shortcuts and other means of accessing Taseditor features instead of using context menu.

        -


        -

        How do I insert a Reset command into the movie?

        -

        You should use Input Recording here. Place the Playback cursor to the target frame, switch on Recording, then choose NES -> Reset in FCEUX main menu and press Frame Advance. Also, it's recommended to set a Marker to this frame, since there's no other way to mark a Reset/Power switch in the Piano Roll (there's no columns for commands, only for buttons).

        -

        Then you can switch Recording off and continue usual movie editing. The frame with the Reset command can be transposed up or down by inserting or deleting frames above it.

        -

        Other hardware commands are invoked the same way, see Controls.

        -


        -

        How do I change the order of columns in the Piano Roll?

        -

        Unfortunately, this feature is not supported in TAS Editor 1.0.  This will be fixed in next versions.

        -


        -

        How do I change the number of players (joypads) in my movie?

        -

        You should create a new project, copying the Input and Markers from the current one.

        -

        Choose File -> New in TAS Editor main menu. In the "Create New Project" window: choose the needed Input type, check "Copy current Input" and "Copy current Markers" checkboxes and click "OK".

        -

        Old project's Bookmarks won't be copied to the new project this way. But you can recreate them using Input export/import features.

        -


        -

        How can I quickly compare two movies?

        -
          -
        1. Make sure that Hot Changes are enabled.
        2. -
        3. Create an empty project, import the first movie into it (using File -> Import Input), replay the movie to the end and save it to Bookmark 1.
        4. -
        5. Import the second movie over the existing Input and save the result to Bookmark 2.
        6. +

          Also, it's recommended to switch the Bookmarks List to the "Branches Tree" view.

          +


          +

          Why the right-click on the FCEUX window doesn't prompt the usual context menu?

          +

          It's done to facilitate the Playback cursor navigation with the mouse wheel.

          +

          Usually users move the mouse cursor in such a manner that it's in sight. Thus when TASer is watching the game events the cursor will often be inside the FCEUX window. Context menus would obstruct the view when you want to rewind the Playback by holding the right mouse button and rolling the mouse wheel. So, since there's no important items in the menu while TAS Editor is engaged, the menu was removed.

          +


          +

          Why the right-click on the Piano Roll sometimes prompts a context menu and sometimes doesn't?

          +

          Taseditor's context menu only appears when you right-click on the number of a selected frame. If you right-click on a frame that is not selected, or you right-click on the Input of a selected frame, the menu won't appear.

          +

          It's done to facilitate the Piano Roll scrolling by right-clicking and dragging.

          +

          Generally, it's recommended to use keyboard shortcuts and other means of accessing Taseditor features instead of using context menu.

          +


          +

          How do I insert a Reset command into the movie?

          +

          You should use Input Recording here. Place the Playback cursor to the target frame, switch on Recording, then choose NES -> Reset in FCEUX main menu and press Frame Advance. Also, it's recommended to set a Marker to this frame, since there's no other way to mark a Reset/Power switch in the Piano Roll (there's no columns for commands, only for buttons).

          +

          Then you can switch Recording off and continue usual movie editing. The frame with the Reset command can be transposed up or down by inserting or deleting frames above it.

          +

          Other hardware commands are invoked the same way, see Controls.

          +


          +

          How do I change the order of columns in the Piano Roll?

          +

          Unfortunately, this feature is not supported in TAS Editor 1.0.  This will be fixed in next versions.

          +


          +

          How do I change the number of players (joypads) in my movie?

          +

          You should create a new project, copying the Input and Markers from the current one.

          +

          Choose File -> New in TAS Editor main menu. In the "Create New Project" window: choose the needed Input type, check "Copy current Input" and "Copy current Markers" checkboxes and click "OK".

          +

          Old project's Bookmarks won't be copied to the new project this way. But you can recreate them using Input export/import features.

          +


          +

          How can I quickly compare two movies?

          +
            +
          1. Make sure that Hot Changes are enabled.
          2. +
          3. Create an empty project, import the first movie into it (using File -> Import Input), replay the movie to the end and save it to Bookmark 1.
          4. +
          5. Import the second movie over the existing Input and save the result to Bookmark 2.
          -

          The import operation will truncate the Greenzone after the frame where the first difference between Input of the two movies was found. Other places of discrepancy can be detected by observing the Input in the Piano Roll:

          -
            -
          • buttonpresses that match in both movies are colored black
          • -
          • new buttonpresses (added by the 2nd movie) are colored bright-red
          • -
          • deleted buttonpresses are marked by dash
          • +

            The import operation will truncate the Greenzone after the frame where the first difference between Input of the two movies was found. Other places of discrepancy can be detected by observing the Input in the Piano Roll:

            +
              +
            • buttonpresses that match in both movies are colored black
            • +
            • new buttonpresses (added by the 2nd movie) are colored bright-red
            • +
            • deleted buttonpresses are marked by dash
            -

            For extra convenience it's recommended to name both Bookmarks, for example, copy/paste the filename of the imported movie into the upper Marker Note just before creating a Bookmark.

            -


            -

            Why are those fm3 files so large?

            -

            An FM3 file usually contains full snapshot of the working process, including the Greenzone data (which takes the most part of the file). See Advanced Features for details. You can customize this in the Config.

            -


            -

            Why is the Manual so long?

            -

            Because besides the program specifications the Manual contains a comprehensive tutorial (the Beginner's Guide) which systematizes known principles of effective TASing. Since there was no similar endeavors before, the author decided that lengthy explanations are the lesser evil than possible inexactitude.

            -


            -


            -


            -


            -


            +

            For extra convenience it's recommended to name both Bookmarks, for example, copy/paste the filename of the imported movie into the upper Marker Note just before creating a Bookmark.

            +


            +

            Why are those fm3 files so large?

            +

            An FM3 file usually contains full snapshot of the working process, including the Greenzone data (which takes the most part of the file). See Advanced Features for details. You can customize this in the Config.

            +


            +

            Why is the Manual so long?

            +

            Because besides the program specifications the Manual contains a comprehensive tutorial (the Beginner's Guide) which systematizes known principles of effective TASing. Since there was no similar endeavors before, the author decided that lengthy explanations are the lesser evil than possible inexactitude.

            +


            +


            +


            +


            +


            -

            Created with the Personal Edition of HelpNDoc: Full-featured Help generator

            -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/FM3format.html b/web/help/taseditor/FM3format.html index 899029a3..111f3bc7 100644 --- a/web/help/taseditor/FM3format.html +++ b/web/help/taseditor/FM3format.html @@ -1,392 +1,635 @@ - - + + + + + - FM3 format - - - - - - - - - - + + + + + + + + FM3 format + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      FM3 format

      - - -
      -
      - Parent - - Previous - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      FM3 format

      + +
      +

      -

      FM3 format

      +

      FM3 format



      -

      The FM3 format is a simple extension of the FM2 format. FM2 files contain data which is needed for replaying the movie, and FM3 just adds Taseditor's working data to the end of FM2 file.

      -

      You can read full specifications of FM2 format in the FCEUX Help and on official site.

      -


      -

      Every FM3 consists of 3 parts:

      -
        -
      • Header (as in fm2)
      • -
      • Input Log (as in fm2)
      • -
      • Taseditor data
      • +

        The FM3 format is a simple extension of the FM2 format. FM2 files contain data which is needed for replaying the movie, and FM3 just adds Taseditor's working data to the end of FM2 file.

        +

        You can read full specifications of FM2 format in the FCEUX Help and on official site.

        +


        +

        Every FM3 consists of 3 parts:

        + -


        -
        -

        -

        -

        Header

        -


        -

        The Header is always in ASCII plain text format.

        -

        It consists of several key-value pairs (lines of text where all symbols before the first space separator are considered to be the keyword and all symbols after this separator are considered to be the text representation of the value).

        -

        Newlines may be \r\n or \n.

        -

        If a line starts from "|" (pipe), it means the end of Header and the beginning of Input Log.

        -


        -

        The key-value pairs may be in any order, except that the first key must be version.

        -

        Value text is always terminated by a newline, which the value text does not include.

        -

        The value text is parsed differently depending on the keyword, it can be either integer or string.

        -


        -

        Keys with integer value:

        -


        -

        (also used for booleans, with a 1 for true and 0 for false)

        -

        (the value can be stored as int32)

        -


        -
          -
        • version (required) – the version of the movie file format; for now it is always 3
        • -
        • emuVersion (required) – the version of the emulator used to produce the file (e.g. 21060)
        • -
        • rerecordCount (optional) – the rerecord count
        • -
        • palFlag (bool) (optional) – true if the movie uses PAL timing
        • -
        • NewPPU (bool) (optional) – true if the movie uses New PPU
        • -
        • FDS (bool) (optional) – true if the movie was recorded on a Famicom Disk System (FDS) game
        • -
        • fourscore (bool) – true if a fourscore was used. If fourscore is not used, then port0 and port1 are required
        • -
        • port0 – the type of input device attached to the port 0. Supported values are:
        • +


          +
          +


          +

          Header

          +


          +

          The Header is always in ASCII plain text format.

          +

          It consists of several key-value pairs (lines of text where all symbols before the first space separator are considered to be the keyword and all symbols after this separator are considered to be the text representation of the value).

          +

          Newlines may be \r\n or \n.

          +

          If a line starts from "|" (pipe), it means the end of Header and the beginning of Input Log.

          +


          +

          The key-value pairs may be in any order, except that the first key must be version.

          +

          Value text is always terminated by a newline, which the value text does not include.

          +

          The value text is parsed differently depending on the keyword, it can be either integer or string.

          +


          +

          Keys with integer value:

          +


          +

          (also used for booleans, with a 1 for true and 0 for false)

          +

          (the value can be stored as int32)

          +


          +
            +
          • version (required) – the version of the movie file format; for now it is always 3
          • +
          • emuVersion (required) – the version of the emulator used to produce the file (e.g. 21060)
          • +
          • rerecordCount (optional) – the rerecord count
          • +
          • palFlag (bool) (optional) – true if the movie uses PAL timing
          • +
          • NewPPU (bool) (optional) – true if the movie uses New PPU
          • +
          • FDS (bool) (optional) – true if the movie was recorded on a Famicom Disk System (FDS) game
          • +
          • fourscore (bool) – true if a fourscore was used. If fourscore is not used, then port0 and port1 are required
          • +
          • port0 – the type of input device attached to the port 0. Supported values are:
          -
            -
          • SI_NONE = 0
          • -
          • SI_GAMEPAD = 1
          • -
          • SI_ZAPPER = 2
          • +
              +
            • SI_NONE = 0
            • +
            • SI_GAMEPAD = 1
            • +
            • SI_ZAPPER = 2
            -
              -
            • port1 – the type of input device attached to the port 1. Supported values are:
            • +
                +
              • port1 – the type of input device attached to the port 1. Supported values are:
              -
                -
              • SI_NONE = 0
              • -
              • SI_GAMEPAD = 1
              • -
              • SI_ZAPPER = 2
              • +
                  +
                • SI_NONE = 0
                • +
                • SI_GAMEPAD = 1
                • +
                • SI_ZAPPER = 2
                -
                  -
                • port2 (required) – the type of the FCExp port device which was attached. Supported values are:
                • +
                    +
                  • port2 (required) – the type of the FCExp port device which was attached. Supported values are:
                  -
                    -
                  • SIFC_NONE = 0
                  • +
                      +
                    • SIFC_NONE = 0
                    -
                      -
                    • binary (bool) (optional) – true if Input Log is stored in binary format. FM2 files usually contain Input in text format, for easy editing and splicing. FM3 files usually contain Input in binary format, to save disk space
                    • -
                    • length (required in FM3) –  movie size (number of frames in the input log). If this key is specified and the number is >= 0, the Input Log ends after specified number of records, and any remaining data should not be parsed (because it's Taseditor data). The Header of FM3s always has this keyword, the Header of FM2s doesn't have it.
                    • +
                        +
                      • binary (bool) (optional) – true if Input Log is stored in binary format. FM2 files usually contain Input in text format, for easy editing and splicing. FM3 files usually contain Input in binary format, to save disk space
                      • +
                      • length (required in FM3) –  movie size (number of frames in the input log). If this key is specified and the number is >= 0, the Input Log ends after specified number of records, and any remaining data should not be parsed (because it's Taseditor data). The Header of FM3s always has this keyword, the Header of FM2s doesn't have it.
                      -


                      -


                      -

                      Keys with string value:

                      -


                      -

                      (their values cannot contain newlines)

                      -


                      -

                      romFilename (required) – the name of the file used to record the movie

                      -

                      romChecksum (required) – the base64 of the hexified MD5 hash of the ROM which was used to record the movie

                      -

                      comment (optional) – simply a memo. By convention, the author of the movie should be stored in a comment with the subject "author". Example: "comment author AnS"

                      -

                      subtitle (optional) – a message that will be displayed on screen when movie is played back (unless Subtitles are turned off). Right after the word "subtitle" and following space separator there must be an integer value indicating the frame that the subtitle will be displayed.  Any remaining text after the integer and following space separator is considered to be the string displayed. Example: "subtitle 100 Level Two" – at frame 100 the words "Level Two" will be displayed on the screen

                      -

                      guid (required) – a unique identifier for a movie, generated when the movie is created. Meaningless in FM3, because all there's no external savestates associated with the project file.

                      -


                      -
                      -

                      -

                      -

                      Input Log

                      -


                      -

                      The Input Log section consists of movie records either in the form of text lines or in the form of binary data.

                      -


                      -


                      -

                      Text format:

                      -


                      -

                      Every frame of the movie is represented by line of text beginning and ending with a "|" (pipe).

                      -


                      -


                      -

                      If fourscore is not used, the fields in the line are as follows:

                      -

                      |commands|port0|port1|port2|

                      -


                      -

                      Field commands is a variable length decimal integer which is interpreted as a bit field corresponding to miscellaneous input states which are valid at the start of the frame. Current values for this are:

                      -
                        -
                      • bit 0 (number = 1) – Soft Reset
                      • -
                      • bit 1 (number = 2) – Power
                      • -
                      • bit 2 (number = 4) – Eject/Insert Disk
                      • -
                      • bit 3 (number = 8) – Switch Disk Side
                      • +


                        +


                        +

                        Keys with string value:

                        +


                        +

                        (their values cannot contain newlines)

                        +


                        +

                        romFilename (required) – the name of the file used to record the movie

                        +

                        romChecksum (required) – the base64 of the hexified MD5 hash of the ROM which was used to record the movie

                        +

                        comment (optional) – simply a memo. By convention, the author of the movie should be stored in a comment with the subject "author". Example: "comment author AnS"

                        +

                        subtitle (optional) – a message that will be displayed on screen when movie is played back (unless Subtitles are turned off). Right after the word "subtitle" and following space separator there must be an integer value indicating the frame that the subtitle will be displayed.  Any remaining text after the integer and following space separator is considered to be the string displayed. Example: "subtitle 100 Level Two" – at frame 100 the words "Level Two" will be displayed on the screen

                        +

                        guid (required) – a unique identifier for a movie, generated when the movie is created. Meaningless in FM3, because all there's no external savestates associated with the project file.

                        +


                        +
                        +


                        +

                        Input Log

                        +


                        +

                        The Input Log section consists of movie records either in the form of text lines or in the form of binary data.

                        +


                        +


                        +

                        Text format:

                        +


                        +

                        Every frame of the movie is represented by line of text beginning and ending with a "|" (pipe).

                        +


                        +


                        +

                        If fourscore is not used, the fields in the line are as follows:

                        +

                        |commands|port0|port1|port2|

                        +


                        +

                        Field commands is a variable length decimal integer which is interpreted as a bit field corresponding to miscellaneous input states which are valid at the start of the frame. Current values for this are:

                        +
                          +
                        • bit 0 (number = 1) – Soft Reset
                        • +
                        • bit 1 (number = 2) – Power
                        • +
                        • bit 2 (number = 4) – Eject/Insert Disk
                        • +
                        • bit 3 (number = 8) – Switch Disk Side
                        -


                        -

                        The format of port0, port1, port2 depends on which types of devices were attached.

                        -
                          -
                        • SI_NONE: the field must be empty
                        • -
                        • SI_GAMEPAD: the field consists of eight characters which constitute a bit field. Any character other than ' ' (spacebar) or '.' (dot) means that the button was pressed. By convention, the following mnemonics are used in a column to remind us of which button corresponds to which column: RLDUTSBA (Right, Left, Down, Up, Start, Select, B, A)
                        • -
                        • SI_ZAPPER: the field consists of several characters in the following pattern XXX YYY B Q Z
                        • +


                          +

                          The format of port0, port1, port2 depends on which types of devices were attached.

                          +
                            +
                          • SI_NONE: the field must be empty
                          • +
                          • SI_GAMEPAD: the field consists of eight characters which constitute a bit field. Any character other than ' ' (spacebar) or '.' (dot) means that the button was pressed. By convention, the following mnemonics are used in a column to remind us of which button corresponds to which column: RLDUTSBA (Right, Left, Down, Up, Start, Select, B, A)
                          • +
                          • SI_ZAPPER: the field consists of several characters in the following pattern XXX YYY B Q Z
                          -
                            -
                          • XXX: %03d – the X position of the mouse
                          • -
                          • YYY: %03d – the Y position of the mouse
                          • -
                          • B: %01d – 1 if the mouse button is pressed; 0 if not
                          • -
                          • Q: %01d – an internal value used by the emulator's zapper code
                          • -
                          • Z: %d – a variable-length decimal integer; an internal value used by the emulator's zapper code
                          • +
                              +
                            • XXX: %03d – the X position of the mouse
                            • +
                            • YYY: %03d – the Y position of the mouse
                            • +
                            • B: %01d – 1 if the mouse button is pressed; 0 if not
                            • +
                            • Q: %01d – an internal value used by the emulator's zapper code
                            • +
                            • Z: %d – a variable-length decimal integer; an internal value used by the emulator's zapper code 
                            -


                            -

                            If fourscore is used, then port0 and port1 are irrelevant and ignored. The input types must all be gamepads, and each input log record must be in the following format:

                            -

                            |commands|RLDUTSBA|RLDUTSBA|RLDUTSBA|RLDUTSBA|port2|

                            -

                            (commands, player 1, player 2, player 3, player 4, port2)

                            -


                            -


                            -

                            Binary format:

                            -


                            -

                            Input Log section starts with a | (pipe).

                            -

                            Every frame of the movie is represented by a record of a fixed length. The length can be determined by the devices on port0 and port1.

                            -


                            -

                            The first byte of each record stores "commands" bit field:

                            -
                              -
                            • bit 0 – Soft Reset
                            • -
                            • bit 1 – Power
                            • -
                            • bit 2 – Eject/Insert Disk
                            • -
                            • bit 3 – Switch Disk Side
                            • +


                              +

                              If fourscore is used, then port0 and port1 are irrelevant and ignored. The input types must all be gamepads, and each input log record must be in the following format:

                              +

                              |commands|RLDUTSBA|RLDUTSBA|RLDUTSBA|RLDUTSBA|port2|

                              +

                              (commands, player 1, player 2, player 3, player 4, port2)

                              +


                              +


                              +

                              Binary format:

                              +


                              +

                              Input Log section starts with a | (pipe).

                              +

                              Every frame of the movie is represented by a record of a fixed length. The length can be determined by the devices on port0 and port1.

                              +


                              +

                              The first byte of each record stores "commands" bit field:

                              +
                                +
                              • bit 0 – Soft Reset
                              • +
                              • bit 1 – Power
                              • +
                              • bit 2 – Eject/Insert Disk
                              • +
                              • bit 3 – Switch Disk Side
                              -


                              -

                              If fourscore is not used, the remaining bytes in the record depend on which types of devices are attached to port0 and port1:

                              -
                                -
                              • SI_NONE: 0 bytes added to the size of record
                              • -
                              • SI_GAMEPAD: 1 byte added to the size of record. Bits of the byte represent the state of buttons (bit0 = A, bit1 = B, bit2 = Select, bit3 = SStart, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right). If the bit is set, respective button is considered to be pressed, if the bit is clear, the button is not pressed
                              • -
                              • SI_ZAPPER: 12 bytes added to the size of record:
                              • +


                                +

                                If fourscore is not used, the remaining bytes in the record depend on which types of devices are attached to port0 and port1:

                                +
                                  +
                                • SI_NONE: 0 bytes added to the size of record
                                • +
                                • SI_GAMEPAD: 1 byte added to the size of record. Bits of the byte represent the state of buttons (bit0 = A, bit1 = B, bit2 = Select, bit3 = SStart, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right). If the bit is set, respective button is considered to be pressed, if the bit is clear, the button is not pressed
                                • +
                                • SI_ZAPPER: 12 bytes added to the size of record:
                                -
                                  -
                                • 1st byte – the X position of the mouse
                                • -
                                • 2nd byte – the Y position of the mouse
                                • -
                                • 3rd byte – 1 if the mouse button is pressed; 0 if not
                                • -
                                • 4th byte – an internal value used by the emulator's zapper code
                                • -
                                • bytes 5-12 (uint64) – an internal value used by the emulator's zapper code
                                • +
                                    +
                                  • 1st byte – the X position of the mouse
                                  • +
                                  • 2nd byte – the Y position of the mouse
                                  • +
                                  • 3rd byte – 1 if the mouse button is pressed; 0 if not
                                  • +
                                  • 4th byte – an internal value used by the emulator's zapper code
                                  • +
                                  • bytes 5-12 (uint64) – an internal value used by the emulator's zapper code
                                  -


                                  -

                                  If fourscore is used, then port0 and port1 are irrelevant and ignored. 4 bytes are added to the size of record. The bits of the 1st byte represent the state of buttons of the 1st joypad (bit0 = A, bit1 = B, bit2 = Select, bit3 = Start, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right); bits of the 2nd byte represent the state of buttons of the 2nd joypad, and so on.

                                  -


                                  -
                                  -

                                  -

                                  -

                                  Taseditor Data

                                  -


                                  -
                                  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +


                                  +

                                  If fourscore is used, then port0 and port1 are irrelevant and ignored. 4 bytes are added to the size of record. The bits of the 1st byte represent the state of buttons of the 1st joypad (bit0 = A, bit1 = B, bit2 = Select, bit3 = Start, bit4 = Up, bit5 = Down, bit6 = Left, bit7 = Right); bits of the 2nd byte represent the state of buttons of the 2nd joypad, and so on.

                                  +


                                  +
                                  +


                                  +

                                  Taseditor Data

                                  +


                                  +
                                  +

                                  4 bytes

                                  -

                                  unsigned int32

                                  -

                                  FM3 version

                                  -

                                  4 bytes

                                  -

                                  unsigned int32

                                  -

                                  Saved modules

                                  -

                                  4 bytes

                                  -

                                  unsigned int32

                                  -

                                  Number of offsets (N = 6)

                                  -

                                  4 * 6 bytes

                                  -

                                  pointers

                                  -

                                  Offsets

                                  -

                                  ???

                                  -

                                  stream

                                  -

                                  MARKERS DATA

                                  -

                                  ???

                                  -

                                  stream

                                  -

                                  BOOKMARKS DATA

                                  -

                                  ???

                                  -

                                  stream

                                  -

                                  GREENZONE DATA

                                  -

                                  ???

                                  -

                                  stream

                                  -

                                  HISTORY DATA

                                  -

                                  ???

                                  -

                                  stream

                                  -

                                  PIANO ROLL DATA

                                  -

                                  ???

                                  -

                                  stream

                                  -

                                  SELECTION DATA

                                  -
                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                  +

                                  4 bytes

                                  +
                                  +

                                  unsigned int32

                                  +
                                  +

                                  FM3 version

                                  +
                                  +

                                  4 bytes

                                  +
                                  +

                                  unsigned int32

                                  +
                                  +

                                  Saved modules

                                  +
                                  +

                                  4 bytes

                                  +
                                  +

                                  unsigned int32

                                  +
                                  +

                                  Number of offsets (N = 6)

                                  +
                                  +

                                  4 * 6 bytes

                                  +
                                  +

                                  pointers

                                  +
                                  +

                                  Offsets

                                  +
                                  +

                                  ???

                                  +
                                  +

                                  stream

                                  +
                                  +

                                  MARKERS DATA

                                  +
                                  +

                                  ???

                                  +
                                  +

                                  stream

                                  +
                                  +

                                  BOOKMARKS DATA

                                  +
                                  +

                                  ???

                                  +
                                  +

                                  stream

                                  +
                                  +

                                  GREENZONE DATA

                                  +
                                  +

                                  ???

                                  +
                                  +

                                  stream

                                  +
                                  +

                                  HISTORY DATA

                                  +
                                  +

                                  ???

                                  +
                                  +

                                  stream

                                  +
                                  +

                                  PIANO ROLL DATA

                                  +
                                  +

                                  ???

                                  +
                                  +

                                  stream

                                  +
                                  +

                                  SELECTION DATA

                                  +
                                  -


                                  -

                                  The data starts right after the last record of the Input Log. If there's EOF after the last record, TAS Editor will interpret the file as an FM2 file.

                                  -


                                  -

                                  First 4 bytes of Taseditor Data contain the version of the project file format. The first release version of TAS Editor 1.0 saves projects with version = 3.

                                  -


                                  -

                                  Next 4 bytes contain bit field that can be used for determining which modules of Taseditor were saved to the FM3 file:

                                  -
                                    -
                                  • bit 0 – Markers were saved
                                  • -
                                  • bit 1 – Bookmarks were saved
                                  • -
                                  • bit 2 – entire Greenzone was saved
                                  • -
                                  • bit 3 – History Log was saved
                                  • -
                                  • bit 4 – Piano Roll position was saved
                                  • -
                                  • bit 5 – Selection History was saved
                                  • +


                                    +

                                    The data starts right after the last record of the Input Log. If there's EOF after the last record, TAS Editor will interpret the file as an FM2 file.

                                    +


                                    +

                                    First 4 bytes of Taseditor Data contain the version of the project file format. The first release version of TAS Editor 1.0 saves projects with version = 3.

                                    +


                                    +

                                    Next 4 bytes contain bit field that can be used for determining which modules of Taseditor were saved to the FM3 file:

                                    +
                                      +
                                    • bit 0 – Markers were saved
                                    • +
                                    • bit 1 – Bookmarks were saved
                                    • +
                                    • bit 2 – entire Greenzone was saved
                                    • +
                                    • bit 3 – History Log was saved
                                    • +
                                    • bit 4 – Piano Roll position was saved
                                    • +
                                    • bit 5 – Selection History was saved
                                    -


                                    -

                                    Next 4 bytes contain the total number of modules, in the version 3 this number must be 6.

                                    -

                                    Then there are six offsets (4 bytes each) pointing at the data of each module. The offsets are counted from the beginning of the file.

                                    -


                                    -

                                    When Taseditor saves the project, it calls all 6 modules that need saving. Each of them saves current writing offset and then serializes its own data into the file stream and moves current write position forward. The order of calling modules is always the same (Markers, Bookmarks, Greenzone, History, Piano Roll, Selection). When loading a project Taseditor calls those modules in the same order and they seek to the given offset and load / deserialize the data from the file.

                                    -

                                    To check the integrity of the data loaded, every module writes its own ID (string) into the file stream before writing the data. When loading the data it expects the ID to match, if it doesn't match then the module refuses to load following data, creates default state and reports "loading error" to Taseditor.

                                    -

                                    When using Save Compact settings, modules either save all their data as usual or write dummy ID which indicates that this module didn't save its data into the file. When loading the file a module that detects dummy ID refuses to load following data, creates default state but then reports "loading success" to Taseditor.

                                    -


                                    -
                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +


                                    +

                                    Next 4 bytes contain the total number of modules, in the version 3 this number must be 6.

                                    +

                                    Then there are six offsets (4 bytes each) pointing at the data of each module. The offsets are counted from the beginning of the file.

                                    +


                                    +

                                    When Taseditor saves the project, it calls all 6 modules that need saving. Each of them saves current writing offset and then serializes its own data into the file stream and moves current write position forward. The order of calling modules is always the same (Markers, Bookmarks, Greenzone, History, Piano Roll, Selection). When loading a project Taseditor calls those modules in the same order and they seek to the given offset and load / deserialize the data from the file.

                                    +

                                    To check the integrity of the data loaded, every module writes its own ID (string) into the file stream before writing the data. When loading the data it expects the ID to match, if it doesn't match then the module refuses to load following data, creates default state and reports "loading error" to Taseditor.

                                    +

                                    When using Save Compact settings, modules either save all their data as usual or write dummy ID which indicates that this module didn't save its data into the file. When loading the file a module that detects dummy ID refuses to load following data, creates default state but then reports "loading success" to Taseditor.

                                    +


                                    +
                                    +

                                    Module

                                    -

                                    ID when saved

                                    -

                                    ID when not saved

                                    -

                                    Markers

                                    -

                                    MARKERS

                                    -

                                    MARKERX

                                    -

                                    Bookmarks

                                    -

                                    BOOKMARKS

                                    -

                                    BOOKMARKX

                                    -

                                    Greenzone

                                    -

                                    GREENZONE

                                    -

                                    GREENZONX

                                    -

                                    History

                                    -

                                    HISTORY

                                    -

                                    HISTORX

                                    -

                                    Piano Roll

                                    -

                                    PIANO_ROLL

                                    -

                                    PIANO_ROLX

                                    -

                                    Selection

                                    -

                                    SELECTION

                                    -

                                    SELECTIOX

                                    -
                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                    +

                                    Module

                                    +
                                    +

                                    ID when saved

                                    +
                                    +

                                    ID when not saved

                                    +
                                    +

                                    Markers

                                    +
                                    +

                                    MARKERS

                                    +
                                    +

                                    MARKERX

                                    +
                                    +

                                    Bookmarks

                                    +
                                    +

                                    BOOKMARKS

                                    +
                                    +

                                    BOOKMARKX

                                    +
                                    +

                                    Greenzone

                                    +
                                    +

                                    GREENZONE

                                    +
                                    +

                                    GREENZONX

                                    +
                                    +

                                    History

                                    +
                                    +

                                    HISTORY

                                    +
                                    +

                                    HISTORX

                                    +
                                    +

                                    Piano Roll

                                    +
                                    +

                                    PIANO_ROLL

                                    +
                                    +

                                    PIANO_ROLX

                                    +
                                    +

                                    Selection

                                    +
                                    +

                                    SELECTION

                                    +
                                    +

                                    SELECTIOX

                                    +
                                    -


                                    -


                                    -


                                    -


                                    -


                                    +


                                    +


                                    +


                                    +


                                    +


                                    -

                                    Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

                                    -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/Glossary.html b/web/help/taseditor/Glossary.html index afb86550..c497de1b 100644 --- a/web/help/taseditor/Glossary.html +++ b/web/help/taseditor/Glossary.html @@ -1,286 +1,475 @@ - - + + + + + - Glossary - - - - - - - - - - + + + + + + + + Glossary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Glossary

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Glossary

      + +
      +

      -

      Glossary

      +

      Glossary



      -

      Here you can find definitions for many terms that are used throughout this Manual. Most of them were used in the context of TASing before TAS Editor was created. Some of those terms are described more thoroughly in the Beginner's Guide.

      -

      It's recommended to read the Glossary at once, because many terms are interconnected.

      -


      -
      -

      -

      -

      -

      Input

      -

      Data about player's actions, that can be received by a game.

      -

      TASing became feasible because of general assumption that behavior of a game is always determined by its initial state and player's input, and nothing else (see Determinism).

      -

      Examples of Input: pressing a button on a gamepad, pushing analog stick, touching by stylus, shouting into a microphone, etc.

      -

      Taseditor works with Input in the form of "sequence of buttons states".

      -

      Note: the fact of player not pressing any button is also considered an Input.

      -

      -

      -

      Output

      -

      Data sent from a game as a result of processing player's Input.

      -

      The process of playing a game can be depicted as a loop of interaction between a subject (player) and an object (game).

      -

      Examples of Output: displaying an image, producing a sound, vibrating gamepad, changing the value of an observed RAM address, providing an information about lag, etc.

      -


      -

      Playthrough / Walkthrough (Solution)

      -

      A sequence of player's actions needed for successful completion of the game.

      -

      This sequence is inputted into the game using an input device (e.g. gamepad). The sequence can be either performed live (created in real-time) or constructed in advance in a form of reproducible recording (e.g. log of button presses). The latter form allows editing of the sequence.

      -


      -

      Speedrun

      -

      A walkthrough aimed on fastest completion of the game.

      -

      Some games have  build-in "Speedrun" or "Time Attack" mode, where the game counts the time spent while playing. For other games it's possible to use external timer, measuring time in seconds or TV frames.

      -


      -

      TAS (Tool-Assisted Superplay / Tool-Assisted Speedrun)

      -

      A walkthrough made with use of tools for editing the sequence of player's actions.

      -

      The process of creating TASes is called "TASing", authors are usually called "TASers".

      -

      The Input editing exempts TASers from certain human limitations (e.g. slow reflexes), allowing to spend full energy on making extraordinary walkthroughs. It can be either speedruns or entertainment videos (playarounds).

      -

      TASes can be distributed:

      -
        -
      • in the form of finished videos containing Output (youtube, AVI files and so on) – easy to watch
      • -
      • in the form of source files containing Input (FM2 movies and so on) – easy to edit
      • +

        Here you can find definitions for many terms that are used throughout this Manual. Most of them were used in the context of TASing before TAS Editor was created. Some of those terms are described more thoroughly in the Beginner's Guide.

        +

        It's recommended to read the Glossary at once, because many terms are interconnected.

        +


        +
        +


        +

        +

        Input

        +

        Data about player's actions, that can be received by a game.

        +

        TASing became feasible because of general assumption that behavior of a game is always determined by its initial state and player's input, and nothing else (see Determinism).

        +

        Examples of Input: pressing a button on a gamepad, pushing analog stick, touching by stylus, shouting into a microphone, etc.

        +

        Taseditor works with Input in the form of "sequence of buttons states".

        +

        Note: the fact of player not pressing any button is also considered an Input.

        +


        +

        Output

        +

        Data sent from a game as a result of processing player's Input.

        +

        The process of playing a game can be depicted as a loop of interaction between a subject (player) and an object (game).

        +

        Examples of Output: displaying an image, producing a sound, vibrating gamepad, changing the value of an observed RAM address, providing an information about lag, etc.

        +


        +

        Playthrough / Walkthrough (Solution)

        +

        A sequence of player's actions needed for successful completion of the game.

        +

        This sequence is inputted into the game using an input device (e.g. gamepad). The sequence can be either performed live (created in real-time) or constructed in advance in a form of reproducible recording (e.g. log of button presses). The latter form allows editing of the sequence.

        +


        +

        Speedrun

        +

        A walkthrough aimed on fastest completion of the game.

        +

        Some games have  build-in "Speedrun" or "Time Attack" mode, where the game counts the time spent while playing. For other games it's possible to use external timer, measuring time in seconds or TV frames.

        +


        +

        TAS (Tool-Assisted Superplay / Tool-Assisted Speedrun)

        +

        A walkthrough made with use of tools for editing the sequence of player's actions.

        +

        The process of creating TASes is called "TASing", authors are usually called "TASers".

        +

        The Input editing exempts TASers from certain human limitations (e.g. slow reflexes), allowing to spend full energy on making extraordinary walkthroughs. It can be either speedruns or entertainment videos (playarounds).

        +

        TASes can be distributed:

        +
          +
        • in the form of finished videos containing Output (youtube, AVI files and so on) – easy to watch
        • +
        • in the form of source files containing Input (FM2 movies and so on) – easy to edit
        -


        -

        Movie (replay)

        -

        Container for storing Input and associated data.

        -

        Unlike video containers, the TAS movies don't contain Output (game footage). The Output appears only when user applies the movie Input to an appropriate game file.

        -


        -

        Lag

        -

        The term used when the delay between Input and Output is greater than normally.

        -

        The loop of interaction between player and game usually establishes some fixed amount of time between polling Input and updating Output, for example 60 times per second.

        -

        A computer processor can only make fixed amount of operations in this fixed amount of time. But videogames try to mimic the unboundedness of real life, so the quantity of in-game objects may vary greatly. Thus it's possible that processing all objects will take more time than allotted. In such cases the Output update will be delayed, and next Input polling will be delayed too.

        -

        Speedrunners try to avoid excessive delays, and the lag is often considered as a factor when TASing. Usually TASers try to minimize the number of "frames containing lag".

        -

        Emulators can detect lag in a frame right after finishing the frame emulation. The criterion is simple: if the game didn't poll Input during the frame then it's the lag frame. If it did poll Input then this is normal frame. Taseditor highlights lag frames with red color, and it's useless to draw any Input on these frames.

        -


        -

        Desync

        -

        Discrepancy between expected and received Output, which results in player's Input not syncing with the logic of the game.

        -

        Desync may appear when the Input made for one game is applied to another game, or using different emulator version or different settings. Also, desyncs appear when emulator doesn't support deterministic emulation.

        -


        -

        Segment

        -

        A part of the movie, representing the period of time between two in-game events.

        -

        Breaking the movie into segments is used to decompose big tasks to smaller subtasks.

        -

        The size of a segment can be measured in frames, but the limits of a segment are usually defined by in-game events. The beginning event cuts all previous tasks and concentrates TASer's attention on the nearest set of conditions. The ending event serves as an optimality criterion for all possible approaches to the current task solution.

        -

        More: TASing Process

        -


        -

        Optimization

        -

        The process of searching for the optimal (the best) solution of the task in current segment.

        -

        Almost any task in videogames can be solved in a variety of ways. Every way has its own pros and cons. When starting a project, TASer chooses his goal (e.g. pacifist speedrun), thus assigning priorities to those pros and cons, therefore all the ways of solving a task can be evaluated and compared to each other to determine which one is better.

        -

        Actual process of TAS optimization consists of editing Input and evaluating resulting Output. When TASer gets better result, he marks current Input as the best, until he finds an even more optimal Input. The final product (TAS movie) contains the best solution for every subtask.

        -

        More: TASing Methodology

        -


        -

        Improvement

        -

        A way to solve the task better (closer to optimum).

        -

        Examples of improvements in speedruns: removing inaccuracy, applying unused timesaver, increasing the usefulness of an old timesaver, adding entertainment without losing speed.

        -


        -

        Timesaver

        -

        Any in-game trick that can save time.

        -

        When making a speedrun, TASer is supposed to use every unprohibited opportunity to make the walkthrough become as fast as possible. One thing is polishing the Input to find the best outcome from current knowledge about the game. Another important activity is expanding this knowledge base – finding and applying tricks. True TASer strives to gather the maximum information about the game and use all known tricks to full extent, so that his record wouldn't be easily beaten.

        -

        Examples of timesavers: features of the game, bugs of the game, luck manipulation.

        -

        Note: sometimes TASers deliberately refuse certain timesavers, in this case the TAS aims for extra category. Examples: Super Mario Bros TAS without using B button (denying certain feature of the game), Sonic the Hedgehog TAS without zipping (denying certain bug of the game).

        -


        -

        Feature

        -

        An intended aspect of the game.

        -

        Some features are unimportant (or even unnoticeable) for an ordinary player, but substantial for a TASer. So, before optimizing Input it's recommended to research the game engine.

        -

        Examples of such features: damage boost, forced waiting for score countdown, coordinate subpixels, AI peculiarities, etc...

        -


        -

        Bug / Glitch

        -

        An unintended aspect of the game.

        -

        Bugs abused by TASer should be reproducible on real console (at least theoretically). Bugs caused by emulation are not permitted.

        -

        Many bugs are discovered during real-time play. Some of them require thorough research and disassembly of the game code.

        -

        Examples of bugs: simplistic collision detection system, not checking save data corruption, race conditions, mistake in the order of checks, etc...

        -


        -

        Luck Manipulation

        -

        Unrestricted exploiting of certain game features, which are normally limited by the shortage of player's knowledge.

        -

        Although any experiments with Input modification are manipulations of game features, but some aspects of games appear especially unpredictable for an ordinary player. Developers intentionally entangle algorithms of those features, so that for a naked eye they seem completely random and uncontrollable.

        -

        However, in deterministic world all aspects of videogames are predictable (defined by Input). Using tools and careful analysis you can reveal those hidden laws and dependencies, and then use the knowledge when creating the Input. And sometimes you don't even have to dissect algorithms, when you can use trial-and-error method.

        -

        More: Nonlinear TASing (example of luck manipulation)

        -


        -

        Subpixels

        -

        The term used when in-game objects have coordinates with fractional parts.

        -

        Generally, there's difference between on-screen coordinates of a sprite and in-game coordinates of the object this sprite represents. In some games those coordinates have the same scale and their values coincide, but usually on-screen images represent a rough outline of the real state of things. So, to get max precision TASers observe the memory of emulated console, using Memory Watch tool or custom Lua HUD. This way also allows to see hidden variables of the game, those that aren't displayed on screen normally.

        -


        -

        Recording

        -

        One of possible ways to create Input for a movie.

        -

        It consists of appending new Input sequentially to the end of current movie, while watching interim results of the Input.

        -

        Another way would be drawing Input directly in the movie.

        -

        More: Toolbox, TASing Methodology, Traditional TASing

        -


        -

        Rerecording

        -

        One of possible ways to edit Input in a movie.

        -

        It consists of rewriting old Input sequentially from starting frame to ending frame, while watching interim results of the Input changes.

        -

        Another way would be direct modification of existing Input in the movie.

        -

        More: TASing Methodology, Traditional TASing, Rerecords counter

        -


        -

        Multitracking (multi-track recording)

        -

        One of ways to record Input for a walkthrough of the game in multi-player mode.

        -

        It consists of recording Input for a segment of the movie by taking turns for every player separately.

        -

        Another way would be recording Input for all players simultaneously.

        -

        More: Toolbox

        -


        -

        Frame Advance

        -

        Step-by-step emulation of a game using the minimum units of measuring time – frames.

        -

        Used for manual control of progression of time. Considered to be more effective replacement to "slow motion".

        -


        -

        Turbo (turbo speed)

        -

        The feature of speeding up emulation to the maximum possible speed.

        -

        Used for skipping meaningless in-game events and reducing waiting time when the emulator is seeking.

        -

        Most emulators allow to customize emulation speed, slowing it down or speeding up when needed. Turbo speed means the fastest speed possible, which is only limited by your computer speed.

        -

        More: Toolbox, Nonlinear TASing, Semiautomatic TASing

        -


        -

        Savestate

        -

        A snapshot of the emulated system's state at that current moment.

        -

        Unlike in-game saves, a savestate contains all the comprehensive data on the state of emulated hardware.

        -


        -

        Piano Roll

        -

        A medium for visual representation of data, similar to table or grid view.

        -

        The interface is used in many music editing programs (MIDI sequencers and MOD trackers). Its name and basic concept was derived from existing storage medium used to operate a mechanic piano (paper rolls).

        -

        Taseditor's Piano Roll displays current movie data (Input and Markers) and allows to edit the data by mouse clicks. It also displays auxiliary information like pointers, Bookmarks, Lag log, etc.

        -

        Every row of the Piano Roll corresponds to one frame of the movie.

        -

        More: Piano Roll, Piano Roll specs

        -


        -

        Playback cursor

        -

        Pointer to currently played frame of the movie.

        -

        Events of this frame are displayed in emulator's main window as current screenshot. Piano Roll marks respective row with light-blue color and the "Play" symbol (light-blue arrow).

        -

        Only one frame of the movie can be seen at any given moment. To see the screenshot of upcoming events you'll have to move the Playback cursor forward (down in the Piano Roll). To see the screenshot of previous events you'll have to move the Playback cursor backward (up in the Piano Roll).

        -

        More: Piano Roll, Playback cursor Navigation

        -


        -

        Greenzone (access zone)

        -

        The storage designed for speeding up Playback cursor navigation.

        -

        This storage automatically collects savestates for all emulated frames of the movie, and when it's necessary to rewind or jump forward to a frame, Taseditor loads respective savestate from Greenzone.

        -

        More: Toolbox, Program Customization, Greenzone specs

        -


        -

        Selection

        -

        Set of rows in the Piano Roll that are highlighted by special color (usually dark-blue).

        -

        Any row of the Piano Roll (and thus any frame of the movie) can be either selected or not selected.

        -

        Selection allows to operate with many frames at once, for example, delete a whole section of the movie at once instead of deleting every single frame in it.

        -

        The upper row of the Selection is called "Selection cursor".

        -

        The Selection cursor automatically follows the process of Input editing.

        -

        More: Piano Roll, Selection cursor Navigation

        -


        -

        Marker

        -

        Yellow mark for a row in Piano Roll that emphasizes the frame among its neighbors.

        -

        Any row in the Piano Roll can be marked. Markers allow to improve the distinctness of movie data.

        -

        Markers can be used to:

        -
          -
        • organize the Input
        • -
        • formalize knowledge (using text Notes)
        • -
        • speed up navigation
        • -
        • speed up selection of segments (Ctrl + A)
        • +


          +

          Movie (replay)

          +

          Container for storing Input and associated data.

          +

          Unlike video containers, the TAS movies don't contain Output (game footage). The Output appears only when user applies the movie Input to an appropriate game file.

          +


          +

          Lag

          +

          The term used when the delay between Input and Output is greater than normally.

          +

          The loop of interaction between player and game usually establishes some fixed amount of time between polling Input and updating Output, for example 60 times per second.

          +

          A computer processor can only make fixed amount of operations in this fixed amount of time. But videogames try to mimic the unboundedness of real life, so the quantity of in-game objects may vary greatly. Thus it's possible that processing all objects will take more time than allotted. In such cases the Output update will be delayed, and next Input polling will be delayed too.

          +

          Speedrunners try to avoid excessive delays, and the lag is often considered as a factor when TASing. Usually TASers try to minimize the number of "frames containing lag".

          +

          Emulators can detect lag in a frame right after finishing the frame emulation. The criterion is simple: if the game didn't poll Input during the frame then it's the lag frame. If it did poll Input then this is normal frame. Taseditor highlights lag frames with red color, and it's useless to draw any Input on these frames.

          +


          +

          Desync

          +

          Discrepancy between expected and received Output, which results in player's Input not syncing with the logic of the game.

          +

          Desync may appear when the Input made for one game is applied to another game, or using different emulator version or different settings. Also, desyncs appear when emulator doesn't support deterministic emulation.

          +


          +

          Segment

          +

          A part of the movie, representing the period of time between two in-game events.

          +

          Breaking the movie into segments is used to decompose big tasks to smaller subtasks.

          +

          The size of a segment can be measured in frames, but the limits of a segment are usually defined by in-game events. The beginning event cuts all previous tasks and concentrates TASer's attention on the nearest set of conditions. The ending event serves as an optimality criterion for all possible approaches to the current task solution.

          +

          More: TASing Process

          +


          +

          Optimization

          +

          The process of searching for the optimal (the best) solution of the task in current segment.

          +

          Almost any task in videogames can be solved in a variety of ways. Every way has its own pros and cons. When starting a project, TASer chooses his goal (e.g. pacifist speedrun), thus assigning priorities to those pros and cons, therefore all the ways of solving a task can be evaluated and compared to each other to determine which one is better.

          +

          Actual process of TAS optimization consists of editing Input and evaluating resulting Output. When TASer gets better result, he marks current Input as the best, until he finds an even more optimal Input. The final product (TAS movie) contains the best solution for every subtask.

          +

          More: TASing Methodology

          +


          +

          Improvement

          +

          A way to solve the task better (closer to optimum).

          +

          Examples of improvements in speedruns: removing inaccuracy, applying unused timesaver, increasing the usefulness of an old timesaver, adding entertainment without losing speed.

          +


          +

          Timesaver

          +

          Any in-game trick that can save time.

          +

          When making a speedrun, TASer is supposed to use every unprohibited opportunity to make the walkthrough become as fast as possible. One thing is polishing the Input to find the best outcome from current knowledge about the game. Another important activity is expanding this knowledge base – finding and applying tricks. True TASer strives to gather the maximum information about the game and use all known tricks to full extent, so that his record wouldn't be easily beaten.

          +

          Examples of timesavers: features of the game, bugs of the game, luck manipulation.

          +

          Note: sometimes TASers deliberately refuse certain timesavers, in this case the TAS aims for extra category. Examples: Super Mario Bros TAS without using B button (denying certain feature of the game), Sonic the Hedgehog TAS without zipping (denying certain bug of the game).

          +


          +

          Feature

          +

          An intended aspect of the game. 

          +

          Some features are unimportant (or even unnoticeable) for an ordinary player, but substantial for a TASer. So, before optimizing Input it's recommended to research the game engine.

          +

          Examples of such features: damage boost, forced waiting for score countdown, coordinate subpixels, AI peculiarities, etc...

          +


          +

          Bug / Glitch

          +

          An unintended aspect of the game. 

          +

          Bugs abused by TASer should be reproducible on real console (at least theoretically). Bugs caused by emulation are not permitted.

          +

          Many bugs are discovered during real-time play. Some of them require thorough research and disassembly of the game code.

          +

          Examples of bugs: simplistic collision detection system, not checking save data corruption, race conditions, mistake in the order of checks, etc...

          +


          +

          Luck Manipulation

          +

          Unrestricted exploiting of certain game features, which are normally limited by the shortage of player's knowledge.

          +

          Although any experiments with Input modification are manipulations of game features, but some aspects of games appear especially unpredictable for an ordinary player. Developers intentionally entangle algorithms of those features, so that for a naked eye they seem completely random and uncontrollable.

          +

          However, in deterministic world all aspects of videogames are predictable (defined by Input). Using tools and careful analysis you can reveal those hidden laws and dependencies, and then use the knowledge when creating the Input. And sometimes you don't even have to dissect algorithms, when you can use trial-and-error method.

          +

          More: Nonlinear TASing (example of luck manipulation)

          +


          +

          Subpixels

          +

          The term used when in-game objects have coordinates with fractional parts.

          +

          Generally, there's difference between on-screen coordinates of a sprite and in-game coordinates of the object this sprite represents. In some games those coordinates have the same scale and their values coincide, but usually on-screen images represent a rough outline of the real state of things. So, to get max precision TASers observe the memory of emulated console, using Memory Watch tool or custom Lua HUD. This way also allows to see hidden variables of the game, those that aren't displayed on screen normally.

          +


          +

          Recording

          +

          One of possible ways to create Input for a movie.

          +

          It consists of appending new Input sequentially to the end of current movie, while watching interim results of the Input.

          +

          Another way would be drawing Input directly in the movie.

          +

          More: Toolbox, TASing Methodology, Traditional TASing

          +


          +

          Rerecording

          +

          One of possible ways to edit Input in a movie.

          +

          It consists of rewriting old Input sequentially from starting frame to ending frame, while watching interim results of the Input changes.

          +

          Another way would be direct modification of existing Input in the movie.

          +

          More: TASing Methodology, Traditional TASing, Rerecords counter

          +


          +

          Multitracking (multi-track recording)

          +

          One of ways to record Input for a walkthrough of the game in multi-player mode.

          +

          It consists of recording Input for a segment of the movie by taking turns for every player separately.

          +

          Another way would be recording Input for all players simultaneously.

          +

          More: Toolbox

          +


          +

          Frame Advance

          +

          Step-by-step emulation of a game using the minimum units of measuring time – frames.

          +

          Used for manual control of progression of time. Considered to be more effective replacement to "slow motion".

          +


          +

          Turbo (turbo speed)

          +

          The feature of speeding up emulation to the maximum possible speed.

          +

          Used for skipping meaningless in-game events and reducing waiting time when the emulator is seeking.

          +

          Most emulators allow to customize emulation speed, slowing it down or speeding up when needed. Turbo speed means the fastest speed possible, which is only limited by your computer speed.

          +

          More: Toolbox, Nonlinear TASing, Semiautomatic TASing

          +


          +

          Savestate

          +

          A snapshot of the emulated system's state at that current moment.

          +

          Unlike in-game saves, a savestate contains all the comprehensive data on the state of emulated hardware.

          +


          +

          Piano Roll

          +

          A medium for visual representation of data, similar to table or grid view.

          +

          The interface is used in many music editing programs (MIDI sequencers and MOD trackers). Its name and basic concept was derived from existing storage medium used to operate a mechanic piano (paper rolls).

          +

          Taseditor's Piano Roll displays current movie data (Input and Markers) and allows to edit the data by mouse clicks. It also displays auxiliary information like pointers, Bookmarks, Lag log, etc.

          +

          Every row of the Piano Roll corresponds to one frame of the movie.

          +

          More: Piano Roll, Piano Roll specs

          +


          +

          Playback cursor

          +

          Pointer to currently played frame of the movie.

          +

          Events of this frame are displayed in emulator's main window as current screenshot. Piano Roll marks respective row with light-blue color and the "Play" symbol (light-blue arrow).

          +

          Only one frame of the movie can be seen at any given moment. To see the screenshot of upcoming events you'll have to move the Playback cursor forward (down in the Piano Roll). To see the screenshot of previous events you'll have to move the Playback cursor backward (up in the Piano Roll).

          +

          More: Piano Roll, Playback cursor Navigation

          +


          +

          Greenzone (access zone)

          +

          The storage designed for speeding up Playback cursor navigation.

          +

          This storage automatically collects savestates for all emulated frames of the movie, and when it's necessary to rewind or jump forward to a frame, Taseditor loads respective savestate from Greenzone.

          +

          More: Toolbox, Program Customization, Greenzone specs

          +


          +

          Selection

          +

          Set of rows in the Piano Roll that are highlighted by special color (usually dark-blue).

          +

          Any row of the Piano Roll (and thus any frame of the movie) can be either selected or not selected.

          +

          Selection allows to operate with many frames at once, for example, delete a whole section of the movie at once instead of deleting every single frame in it.

          +

          The upper row of the Selection is called "Selection cursor".

          +

          The Selection cursor automatically follows the process of Input editing.

          +

          More: Piano Roll, Selection cursor Navigation

          +


          +

          Marker

          +

          Yellow mark for a row in Piano Roll that emphasizes the frame among its neighbors.

          +

          Any row in the Piano Roll can be marked. Markers allow to improve the distinctness of movie data.

          +

          Markers can be used to:

          +
            +
          • organize the Input
          • +
          • formalize knowledge (using text Notes)
          • +
          • speed up navigation
          • +
          • speed up selection of segments (Ctrl + A)
          -

          More: Piano Roll, Markers specs

          -


          -

          Note

          -

          A single line of text accompanying every Marker.

          -

          More: Piano Roll, Controls, Advanced Features

          -


          -

          Bookmark

          -

          A numbered mark for a frame of the movie.

          -

          Taseditor has 10 slots for Bookmarks.

          -

          A Bookmark stores all necessary data about the frame it was placed on. Including the movie branch that contains an Input that definitely leads the game to the events of this frame.

          -

          Bookmarks can be used for Playback cursor navigation, but their main purpose is to store branches.

          -

          More: Toolbox, Bookmarks specs

          -


          -

          Branch

          -

          A full copy of the movie, storing its state at the moment of creating the Bookmark.

          -

          The current movie can be replaced by the branch when necessary, thus restoring saved state of the movie.

          -

          With branches you can have many different movies in one project, and you can instantly switch among them:

          -
            -
          • to compare alternative strategies of walkthrough
          • -
          • to store current best approach when testing different solutions in a segment
          • -
          • to store examples of unused tricks that could be useful in future
          • -
          • to compare your own movie with somebody else's movie (e.g. when making an improvement)
          • +

            More: Piano Roll, Markers specs

            +


            +

            Note

            +

            A single line of text accompanying every Marker.

            +

            More: Piano Roll, Controls, Advanced Features

            +


            +

            Bookmark

            +

            A numbered mark for a frame of the movie.

            +

            Taseditor has 10 slots for Bookmarks.

            +

            A Bookmark stores all necessary data about the frame it was placed on. Including the movie branch that contains an Input that definitely leads the game to the events of this frame.

            +

            Bookmarks can be used for Playback cursor navigation, but their main purpose is to store branches.

            +

            More: Toolbox, Bookmarks specs

            +


            +

            Branch

            +

            A full copy of the movie, storing its state at the moment of creating the Bookmark.

            +

            The current movie can be replaced by the branch when necessary, thus restoring saved state of the movie.

            +

            With branches you can have many different movies in one project, and you can instantly switch among them:

            +
              +
            • to compare alternative strategies of walkthrough
            • +
            • to store current best approach when testing different solutions in a segment
            • +
            • to store examples of unused tricks that could be useful in future
            • +
            • to compare your own movie with somebody else's movie (e.g. when making an improvement)
            -

            More: Toolbox, Program Customization, Branches specs

            -


            -

            Project

            -

            Container for storing working data in Taseditor.

            -

            More: Advanced Features

            -


            -

            Lua

            -

            Programming language used in many TAS-friendly emulators.

            -

            Useful for making custom tools and for data visualization.

            -

            More: Advanced Features, Lua, Lua API

            -


            -

            Bot (robot)

            -

            A program made for automation of a specific task.

            -

            Bots are created to free humans from tedious work that doesn't require high intelligence. Unlike humans, bots don't invent the solution, they just methodically test all possible approaches within given limits, following an algorithm made by the programmer.

            -

            Nowadays bots are only practical for running exhaustive search within a very small segment of the movie. Most of time it's faster to search for best solution manually, using human intuition to eliminate dead ends without unnecessary tests.

            -

            Making bots requires programming skills. TASing bots are either written in Lua or built-in into emulators by modifying an open source code.

            -


            -

            Pattern

            -

            A predefined sequence of Input values for a button.

            -

            More: Advanced Features, Patterns specs

            -


            -


            -


            -


            -


            +

            More: Toolbox, Program Customization, Branches specs

            +


            +

            Project

            +

            Container for storing working data in Taseditor.

            +

            More: Advanced Features

            +


            +

            Lua

            +

            Programming language used in many TAS-friendly emulators.

            +

            Useful for making custom tools and for data visualization.

            +

            More: Advanced Features, Lua, Lua API

            +


            +

            Bot (robot)

            +

            A program made for automation of a specific task.

            +

            Bots are created to free humans from tedious work that doesn't require high intelligence. Unlike humans, bots don't invent the solution, they just methodically test all possible approaches within given limits, following an algorithm made by the programmer.

            +

            Nowadays bots are only practical for running exhaustive search within a very small segment of the movie. Most of time it's faster to search for best solution manually, using human intuition to eliminate dead ends without unnecessary tests.

            +

            Making bots requires programming skills. TASing bots are either written in Lua or built-in into emulators by modifying an open source code.

            +


            +

            Pattern

            +

            A predefined sequence of Input values for a button.

            +

            More: Advanced Features, Patterns specs

            +


            +


            +


            +


            +


            -

            Created with the Personal Edition of HelpNDoc: Free EBook and documentation generator

            -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/Ideas.html b/web/help/taseditor/Ideas.html index 66ce19c7..bfb8ca69 100644 --- a/web/help/taseditor/Ideas.html +++ b/web/help/taseditor/Ideas.html @@ -1,593 +1,760 @@ - - + + + + + - Ideas - - - - - - - - - - + + + + + + + + Ideas + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Ideas

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Ideas

      + +
      +

      -

      Ideas

      +

      Ideas



      -

      Taseditor combines multiple experimental ideas into single system. Many of these ideas appeared long ago (see topics on the forum, like "dream tool", etc.), but it took a long time to implement them in terms of a consistent system.

      -

      The underlying idea of Taseditor is the Piano Roll interface that allows user to interact with the movie in a very intuitive from. The first mention of the need for a Piano Roll-based TAS tool sounded back in 2005, perhaps even earlier. A prototype called TASEdit was made in 2008. The final vision of Taseditor was formed in September 2011 and was improved during the course of development until the summer of 2012. In addition to the ideas implemented at that time, many promising but minor or hard-to-implement ideas were invented and postponed for the future.

      -


      -
      - - - - - - - - +

      Taseditor combines multiple experimental ideas into single system. Many of these ideas appeared long ago (see topics on the forum, like "dream tool", etc.), but it took a long time to implement them in terms of a consistent system.

      +

      The underlying idea of Taseditor is the Piano Roll interface that allows user to interact with the movie in a very intuitive from. The first mention of the need for a Piano Roll-based TAS tool sounded back in 2005, perhaps even earlier. A prototype called TASEdit was made in 2008. The final vision of Taseditor was formed in September 2011 and was improved during the course of development until the summer of 2012. In addition to the ideas implemented at that time, many promising but minor or hard-to-implement ideas were invented and postponed for the future.

      +


      +
      +

      Implemented in 1.0

      -

      Planned for 2.0

      -

      Piano Roll

      -

      Selection

      -

      Markers

      -

      Hot Changes

      -

      Greenzone

      -

      Playback

      -

      Green arrow

      -

      Auto-restore last position

      -

      Multitrack Recorder

      -

      Lua automation

      -

      Bookmarks and branches

      -

      Pop-up windows

      -

      History Log

      -

      Rerecord counter

      -

      Modifier keys system

      -

      Patterns

      -

      Crossing gaps

      -

      Compact saving

      -

      Autosave

      -

      Output Log

      -

      Minimap

      -

      Virtual Joypad

      -

      Selection improvement

      -

      Columns tweaking

      -

      Rerecords heatmap

      -

      Other stuff

      -

      Supporting platforms other than NES

      -
      + + + + + + + +
      +

      Implemented in 1.0

      +
      +

      Planned for 2.0

      +
      +

      Piano Roll

      +

      Selection

      +

      Markers

      +

      Hot Changes

      +

      Greenzone

      +

      Playback

      +

      Green arrow

      +

      Auto-restore last position

      +

      Multitrack Recorder

      +

      Lua automation

      +

      Bookmarks and branches

      +

      Pop-up windows

      +

      History Log

      +

      Rerecord counter

      +

      Modifier keys system

      +

      Patterns

      +

      Crossing gaps

      +

      Compact saving

      +

      Autosave

      +
      +

      Output Log

      +

      Minimap

      +

      Virtual Joypad

      +

      Selection improvement

      +

      Columns tweaking

      +

      Rerecords heatmap

      +

      Other stuff

      +

      Supporting platforms other than NES

      +
      -


      -
      -

      -

      -

      Implemented ideas

      -

      -

      -

      Piano Roll

      -


      -

      The basis of Taseditor, all other ideas were developed around this one.

      -


      -
        -
      • It is a significantly redesigned List (ListView) or Table (GridView) component. Columns of the List correspond to Input buttons, rows of the List correspond to movie frames. The number of rows (lines) in the List is regularly updated automatically to match the number of frames in the current movie. The lines are numbered from top to bottom, starting from zero. The line number is equal to the number of frame associated with this line. The number of columns depends on the movie type (on the number of joypads and the number of buttons).
      • -
      • To the left from the Input columns there are two additional columns in the List. The first column (width ~17 pixels) is responsible for displaying icons and controlling the Playback cursor. Current Playback cursor position is displayed with a light-blue arrow icon. When you left-click on that column, the Playback cursor is sent to the appropriate frame, and then you can drag the cursor by moving the mouse, until you release the left button.
      • -
      • The second column (75 pixels wide) is responsible for displaying frame numbers and Markers, and for controlling the Selection and Markers. A single left-click on the column changes the Selection (and then you can stretch it by dragging). A double-click on a frame number puts a Marker there and starts dragging this Marker until you release the left mouse button.
      • -
      • The List Header displays names of the columns. The first column (icons column) does not have a name, the second column is called "Frame #" (frame number), the remaining columns are named with corresponding joypad button symbols. The same symbol appears in the cells of the column on the rows where the button is pressed. The user can click any cell of the List Header in order to change the appropriate button Input in the selected frames. Click the "Frame #" to change Markers in the selected frames.
      • -
      • In addition, the Header serves as an indicator of the pressed joypad buttons. And during Input Recording, the recorded symbols flash in the Header.
      • -
      • Input columns show the state of every joypad button for each frame of the movie. To see the state of the button of interest, you need to visually find the point of intersection of the frame row and the button column. If this cell contains a button symbol, then the button is pressed in this frame. If that cell is empty or has a dash, then the button is released. By left-clicking on any Input cell you can invert the state of the corresponding button. Also, if you hold the left mouse button, you can draw or erase Input in neighboring frames by moving your mouse up or down.
      • -
      • Piano Roll lines are colored with different pastel colors, so the frame numbers (black symbols) and the buttonpress symbols (dark-colored symbols) are always clearly visible on the pastel background. By the color of a Piano Roll line you can immediately determine if this movie frame is inside the Greenzone, whether there is lag in that frame, whether the given frame is currently displayed in the emulator window, and is the frame selected or not. Also, additional colors can focus the user's attention on specific frames, for example, on the target frame of seeking (flashing light-blue line) or the undo keyframe (purple line). In addition, by the background color of the frame numbers the user can see if there is Marker on the frame (yellow color).
      • -
      • The coloring of the Piano Roll cells also depends on the column (although to a lesser extent). Icon column always appears in white. Frame numbers column is displayed with pale shade of the current line color. The columns of the 1st (and 3rd) joypad buttons appear in normal shade of the current line color (green, red, blue, etc.), and the columns of the 2nd (and 4th) joypad buttons are displayed in a slightly tinted shade of this line color.
      • -
      • The visible area of the Piano Roll can be scrolled with the mouse wheel or by using the scrollbar, or a variety of other navigation methods. Such multitude of methods is meant to speed up the navigation to any desired segment of the movie, since only a limited number of lines can be displayed on screen at any given moment. This number depends on the current Piano Roll height in pixels, which depends on the current TAS Editor window height.
      • +


        +
        +


        +

        Implemented ideas

        +


        +

        Piano Roll

        +


        +

        The basis of Taseditor, all other ideas were developed around this one.

        +


        +
          +
        • It is a significantly redesigned List (ListView) or Table (GridView) component. Columns of the List correspond to Input buttons, rows of the List correspond to movie frames. The number of rows (lines) in the List is regularly updated automatically to match the number of frames in the current movie. The lines are numbered from top to bottom, starting from zero. The line number is equal to the number of frame associated with this line. The number of columns depends on the movie type (on the number of joypads and the number of buttons).
        • +
        • To the left from the Input columns there are two additional columns in the List. The first column (width ~17 pixels) is responsible for displaying icons and controlling the Playback cursor. Current Playback cursor position is displayed with a light-blue arrow icon. When you left-click on that column, the Playback cursor is sent to the appropriate frame, and then you can drag the cursor by moving the mouse, until you release the left button.
        • +
        • The second column (75 pixels wide) is responsible for displaying frame numbers and Markers, and for controlling the Selection and Markers. A single left-click on the column changes the Selection (and then you can stretch it by dragging). A double-click on a frame number puts a Marker there and starts dragging this Marker until you release the left mouse button.
        • +
        • The List Header displays names of the columns. The first column (icons column) does not have a name, the second column is called "Frame #" (frame number), the remaining columns are named with corresponding joypad button symbols. The same symbol appears in the cells of the column on the rows where the button is pressed. The user can click any cell of the List Header in order to change the appropriate button Input in the selected frames. Click the "Frame #" to change Markers in the selected frames.
        • +
        • In addition, the Header serves as an indicator of the pressed joypad buttons. And during Input Recording, the recorded symbols flash in the Header.
        • +
        • Input columns show the state of every joypad button for each frame of the movie. To see the state of the button of interest, you need to visually find the point of intersection of the frame row and the button column. If this cell contains a button symbol, then the button is pressed in this frame. If that cell is empty or has a dash, then the button is released. By left-clicking on any Input cell you can invert the state of the corresponding button. Also, if you hold the left mouse button, you can draw or erase Input in neighboring frames by moving your mouse up or down.
        • +
        • Piano Roll lines are colored with different pastel colors, so the frame numbers (black symbols) and the buttonpress symbols (dark-colored symbols) are always clearly visible on the pastel background. By the color of a Piano Roll line you can immediately determine if this movie frame is inside the Greenzone, whether there is lag in that frame, whether the given frame is currently displayed in the emulator window, and is the frame selected or not. Also, additional colors can focus the user's attention on specific frames, for example, on the target frame of seeking (flashing light-blue line) or the undo keyframe (purple line). In addition, by the background color of the frame numbers the user can see if there is Marker on the frame (yellow color).
        • +
        • The coloring of the Piano Roll cells also depends on the column (although to a lesser extent). Icon column always appears in white. Frame numbers column is displayed with pale shade of the current line color. The columns of the 1st (and 3rd) joypad buttons appear in normal shade of the current line color (green, red, blue, etc.), and the columns of the 2nd (and 4th) joypad buttons are displayed in a slightly tinted shade of this line color.
        • +
        • The visible area of the Piano Roll can be scrolled with the mouse wheel or by using the scrollbar, or a variety of other navigation methods. Such multitude of methods is meant to speed up the navigation to any desired segment of the movie, since only a limited number of lines can be displayed on screen at any given moment. This number depends on the current Piano Roll height in pixels, which depends on the current TAS Editor window height.
        -

        -

        -

        Selection

        -


        -

        As in any other editor, in Taseditor the Selection is used to apply an operation to multiple frames at once. But in addition, here the Selection also serves as a pointer (cursor) to the last edited Input location.

        -


        -
          -
        • The Selection is stored as a list of numbers of frames that are considered selected.
        • -
        • Taseditor also stores the Selections Log in memory, as an array of lists. The array size is equal to the the History Log size. You can return to the previous selections with Ctrl + Q and Ctrl + W. This is useful for tracking the recent history of clicks on the Piano Roll.
        • -
        • The Piano Roll column of frame numbers is used to control the Selection. If you hold the left button after you click on the frame number, you can stretch the Selection to adjacent frames. If you hold down the Ctrl key before clicking on a frame number, the previously selected frames remain highlighted, but if you make a simple click on a frame number or on Input, the current selection disappears (moves into the Selection history), and a new selection is created instead, consisting of one frame (which was clicked). If you hold down Shift before clicking on a frame number, you will select all the frames starting from the old Selection to the clicked frame. If you hold down Alt before clicking on a frame number, a pattern-based Selection will appear. Selection also changes when you click on Input cells, but only if the modifier keys are not held.
        • -
        • The topmost selected frame is called Selection cursor. If currently not a single frame is selected, it is implied that the Selection cursor points to the frame -1. This is necessary in some situations, for example, when there's no Selection, the bottom edit field displays the Note of the zeroth Marker.
        • -
        • The Selection Log (including the current Selection) is saved and loaded from the project file. When you change the "max undo levels" setting, it will change both the size of the History Log and the Selection Log.
        • -
        • While inserting and removing frames, the current Selection is automatically shifted up or down by a corresponding number of lines, in order to remain in the same position (relative to Input).
        • -
        • Current Selection can be moved (Ctrl + Up / Ctrl + Down / Ctrl + Home / Ctrl + End). If some part of the Selection goes beyond Piano Roll, this part disappears. That is, the user can not select any frame beyond the current movie.
        • -
        • The Selection cursor can jump on Markers (Ctrl + Page Up / Ctrl + Page Down), with each jump the current Selection goes to History and a newly selected frame appears at the next Marker.
        • -
        • The visible area of the Piano Roll always follows the Selection. If the selection does not fit the screen, Piano Roll scrolls in such a way that the Selection cursor is in the middle, but if the selection fits, the Piano Roll shows all selected frames.
        • -
        • The bottom text edit field displays the Note of the nearest Marker above the Selection cursor. This text is updated every time the Selection changes or you change Markers.
        • -
        • When you press Ctrl + A, the current Selection goes to History, and instead it selects the frames starting with the nearest Marker above the Selection cursor and ending with the next Marker (not including that Marker). This way you can select the whole segment. At the second Ctrl + A press, the Selection changes to a set of frames between the Markers, not including the upper and lower Markers. On the third Ctrl + A press, the Selection will change to a set of frames between the Markers, excluding the upper but including the lower Marker. Finally, the fourth Ctrl + A pressing modifies the Selection into a set of frames between the Markers, including both Markers. All the next Ctrl + A presses will repeat these four versions of the selection.
        • +


          +

          Selection

          +


          +

          As in any other editor, in Taseditor the Selection is used to apply an operation to multiple frames at once. But in addition, here the Selection also serves as a pointer (cursor) to the last edited Input location.

          +


          +
            +
          • The Selection is stored as a list of numbers of frames that are considered selected.
          • +
          • Taseditor also stores the Selections Log in memory, as an array of lists. The array size is equal to the the History Log size. You can return to the previous selections with Ctrl + Q and Ctrl + W. This is useful for tracking the recent history of clicks on the Piano Roll.
          • +
          • The Piano Roll column of frame numbers is used to control the Selection. If you hold the left button after you click on the frame number, you can stretch the Selection to adjacent frames. If you hold down the Ctrl key before clicking on a frame number, the previously selected frames remain highlighted, but if you make a simple click on a frame number or on Input, the current selection disappears (moves into the Selection history), and a new selection is created instead, consisting of one frame (which was clicked). If you hold down Shift before clicking on a frame number, you will select all the frames starting from the old Selection to the clicked frame. If you hold down Alt before clicking on a frame number, a pattern-based Selection will appear. Selection also changes when you click on Input cells, but only if the modifier keys are not held.
          • +
          • The topmost selected frame is called Selection cursor. If currently not a single frame is selected, it is implied that the Selection cursor points to the frame -1. This is necessary in some situations, for example, when there's no Selection, the bottom edit field displays the Note of the zeroth Marker.
          • +
          • The Selection Log (including the current Selection) is saved and loaded from the project file. When you change the "max undo levels" setting, it will change both the size of the History Log and the Selection Log.
          • +
          • While inserting and removing frames, the current Selection is automatically shifted up or down by a corresponding number of lines, in order to remain in the same position (relative to Input).
          • +
          • Current Selection can be moved (Ctrl + Up / Ctrl + Down / Ctrl + Home / Ctrl + End). If some part of the Selection goes beyond Piano Roll, this part disappears. That is, the user can not select any frame beyond the current movie.
          • +
          • The Selection cursor can jump on Markers (Ctrl + Page Up / Ctrl + Page Down), with each jump the current Selection goes to History and a newly selected frame appears at the next Marker.
          • +
          • The visible area of the Piano Roll always follows the Selection. If the selection does not fit the screen, Piano Roll scrolls in such a way that the Selection cursor is in the middle, but if the selection fits, the Piano Roll shows all selected frames.
          • +
          • The bottom text edit field displays the Note of the nearest Marker above the Selection cursor. This text is updated every time the Selection changes or you change Markers.
          • +
          • When you press Ctrl + A, the current Selection goes to History, and instead it selects the frames starting with the nearest Marker above the Selection cursor and ending with the next Marker (not including that Marker). This way you can select the whole segment. At the second Ctrl + A press, the Selection changes to a set of frames between the Markers, not including the upper and lower Markers. On the third Ctrl + A press, the Selection will change to a set of frames between the Markers, excluding the upper but including the lower Marker. Finally, the fourth Ctrl + A pressing modifies the Selection into a set of frames between the Markers, including both Markers. All the next Ctrl + A presses will repeat these four versions of the selection.
          -

          -

          -

          Markers

          -


          -

          When editing large movies, the user may need to set some marks on the Piano Roll lines, in order to distinct these lines visually from their neighbors. After a series of improvements, that simple idea evolved into a versatile feature.

          -


          -
            -
          • Any frame of the movie can be marked. If necessary, the user can even mark all movie frames. Also, you can leave a mark, say, on a frame 1200, and then truncate the Input after frame 1000, leaving the Input-detached Marker outside the movie boundary. This Marker will remain in the project. To see it, you would need to emulate the game up to frame 1200 again, so the Piano Roll displays the marked line.
          • -
          • Unmarked Piano Roll lines are displayed in normal colors, but in the marked lines the frame number cell is colored yellow. This color is chosen because Markers are intended to attract user's attention. Also the numbers of marked frames are written using special font, so that the Marker presence can be guessed even when the yellow background is covered by the blue Selection color.
          • -
          • Markers can be attached to the Input (then they are displayed by pale yellow), or can be detached (displayed by more saturated yellow). When the Markers are attached, they are affected by all operations that move Input up/down, and affected by Input truncation.
          • -
          • A Marker can be set by double-clicking (with the left mouse button) on the desired frame number. If you double-click on an already existing Marker, you will start dragging it until you release the left button. So you can move the Marker to another frame, or remove a Marker by throwing it away from the Piano Roll. When you drag it, a Marker image is hanging under the mouse cursor, looking like a yellow rectangle with the number of the frame it was taken from. To cancel the dragging, either drop the Marker on the same cell, or drop it on any Input cell.
          • -
          • Markers can also be created and removed using the context menu or by clicking on the "Frame#" caption.
          • -
          • Usually Markers are placed far from each other, so there are intervals of unmarked frames between them. Therefore, Markers can be used not only as color highlighting for special frames, but also as border marks for movie segments. The following terminology is used: each Marker corresponds to the movie segment that starts with the marked frame and ends with the last unmarked frame. For example, if Markers are set at the frames 10 and 20, we are calling the range of frames 10-19 as a "segment of the first Marker", and the segment of the second Marker consists of all the frames from the frame 20 to the last movie frame.
          • -
          • The intervals between the Markers can be crossed by jumping from the current Marker to the next one (or previous). This allows to speed up the navigation through the movie in some cases.
          • -
          • With the Select between Markers function (Ctrl + A) the user can quickly select all frames in the current Marker segment. Thus Markers can accelerate not only navigation, but also editing.
          • -
          • Each Marker has a text Note. After Marker creation it is empty. The user can view and edit the Note using any of the two text edit fields. In the upper edit field you can see the Note of the Marker above the current Playback cursor. The lower edit field displays the Note of the Marker above the Selection cursor. So, to edit the desired Note, you must first put one of the two cursors below desired Marker or right into the Marker. In theory it sounds awkward, but in Taseditor the general workflow ensures that one of the cursors is usually located under the needed Marker.
          • -
          • The Note size is limited by one hundred of characters, because Notes are not intended to store long texts, they are for short comments, tags and similar kinds of napkin notes. In an extreme case you can always place multiple Markers in a row and break the long text into several adjacent Notes.
          • -
          • You can make a regular search through Notes text (Find Note) or fuzzy search (Similar/More). See more in Advanced Features.
          • -
          • Markers are saved and restored from the Bookmark branches along with Input. Each Marker operation is recorded to History Log the same way as Input operations. Also, the current state of Markers is saved into the project file, right after saving the Input data.
          • +


            +

            Markers

            +


            +

            When editing large movies, the user may need to set some marks on the Piano Roll lines, in order to distinct these lines visually from their neighbors. After a series of improvements, that simple idea evolved into a versatile feature.

            +


            +
              +
            • Any frame of the movie can be marked. If necessary, the user can even mark all movie frames. Also, you can leave a mark, say, on a frame 1200, and then truncate the Input after frame 1000, leaving the Input-detached Marker outside the movie boundary. This Marker will remain in the project. To see it, you would need to emulate the game up to frame 1200 again, so the Piano Roll displays the marked line.
            • +
            • Unmarked Piano Roll lines are displayed in normal colors, but in the marked lines the frame number cell is colored yellow. This color is chosen because Markers are intended to attract user's attention. Also the numbers of marked frames are written using special font, so that the Marker presence can be guessed even when the yellow background is covered by the blue Selection color.
            • +
            • Markers can be attached to the Input (then they are displayed by pale yellow), or can be detached (displayed by more saturated yellow). When the Markers are attached, they are affected by all operations that move Input up/down, and affected by Input truncation.
            • +
            • A Marker can be set by double-clicking (with the left mouse button) on the desired frame number. If you double-click on an already existing Marker, you will start dragging it until you release the left button. So you can move the Marker to another frame, or remove a Marker by throwing it away from the Piano Roll. When you drag it, a Marker image is hanging under the mouse cursor, looking like a yellow rectangle with the number of the frame it was taken from. To cancel the dragging, either drop the Marker on the same cell, or drop it on any Input cell.
            • +
            • Markers can also be created and removed using the context menu or by clicking on the "Frame#" caption.
            • +
            • Usually Markers are placed far from each other, so there are intervals of unmarked frames between them. Therefore, Markers can be used not only as color highlighting for special frames, but also as border marks for movie segments. The following terminology is used: each Marker corresponds to the movie segment that starts with the marked frame and ends with the last unmarked frame. For example, if Markers are set at the frames 10 and 20, we are calling the range of frames 10-19 as a "segment of the first Marker", and the segment of the second Marker consists of all the frames from the frame 20 to the last movie frame.
            • +
            • The intervals between the Markers can be crossed by jumping from the current Marker to the next one (or previous). This allows to speed up the navigation through the movie in some cases.
            • +
            • With the Select between Markers function (Ctrl + A) the user can quickly select all frames in the current Marker segment. Thus Markers can accelerate not only navigation, but also editing.
            • +
            • Each Marker has a text Note. After Marker creation it is empty. The user can view and edit the Note using any of the two text edit fields. In the upper edit field you can see the Note of the Marker above the current Playback cursor. The lower edit field displays the Note of the Marker above the Selection cursor. So, to edit the desired Note, you must first put one of the two cursors below desired Marker or right into the Marker. In theory it sounds awkward, but in Taseditor the general workflow ensures that one of the cursors is usually located under the needed Marker.
            • +
            • The Note size is limited by one hundred of characters, because Notes are not intended to store long texts, they are for short comments, tags and similar kinds of napkin notes. In an extreme case you can always place multiple Markers in a row and break the long text into several adjacent Notes.
            • +
            • You can make a regular search through Notes text (Find Note) or fuzzy search (Similar/More). See more in Advanced Features.
            • +
            • Markers are saved and restored from the Bookmark branches along with Input. Each Marker operation is recorded to History Log the same way as Input operations. Also, the current state of Markers is saved into the project file, right after saving the Input data.
            -

            -

            -

            Hot Changes

            -


            -

            Taseditor paints text symbols in the Input cells by different colors, depending on the time of editing the cell. For details, see Program Interface and Program Customization.

            -


            -
              -
            • Taseditor stores the hotness value for all the Input cells, despite the fact that majority of them has zero hotness. It is necessary for the rare occasions when almost all movie cells become mass-changed (e.g, Import or Paste operations). Thus the array of Hot Changes takes a lot of memory, but it is well compressed and takes little space on the disk.
            • -
            • Using 16 shades of color, so that one byte can fit the data about hotness of 2 cells. Also, it makes no sense to add more grades, since the human eye will hardly distinguish them, while the value of the Hot Changes is in the ability to quickly estimate Input without long deliberation.
            • -
            • The state of the current Hot Changes map changes only when a new item is added to the History Log (and during History undos).
            • +


              +

              Hot Changes

              +


              +

              Taseditor paints text symbols in the Input cells by different colors, depending on the time of editing the cell. For details, see Program Interface and Program Customization.

              +


              +
                +
              • Taseditor stores the hotness value for all the Input cells, despite the fact that majority of them has zero hotness. It is necessary for the rare occasions when almost all movie cells become mass-changed (e.g, Import or Paste operations). Thus the array of Hot Changes takes a lot of memory, but it is well compressed and takes little space on the disk.
              • +
              • Using 16 shades of color, so that one byte can fit the data about hotness of 2 cells. Also, it makes no sense to add more grades, since the human eye will hardly distinguish them, while the value of the Hot Changes is in the ability to quickly estimate Input without long deliberation.
              • +
              • The state of the current Hot Changes map changes only when a new item is added to the History Log (and during History undos).
              -
                -
              • when changing Input, all old cells lose one level of hotness, and changed cells gain maximum level
              • -
              • when removing frames, old cells lose one hotness level
              • -
              • when inserting frames, old cells lose one hotness level, and all the inserted frames cells appear with maximum level
              • -
              • when editing Markers or Bookmarks, and when truncating the movie, Hot Changes do not change
              • -
              • when loading a Bookmark, the current Hot Changes are replaced by the Hot Changes from the Bookmark branch
              • -
              • when importing Input, the old cells are reset to zero hotness, and changed cells gain maximum level
              • +
                  +
                • when changing Input, all old cells lose one level of hotness, and changed cells gain maximum level
                • +
                • when removing frames, old cells lose one hotness level
                • +
                • when inserting frames, old cells lose one hotness level, and all the inserted frames cells appear with maximum level
                • +
                • when editing Markers or Bookmarks, and when truncating the movie, Hot Changes do not change
                • +
                • when loading a Bookmark, the current Hot Changes are replaced by the Hot Changes from the Bookmark branch
                • +
                • when importing Input, the old cells are reset to zero hotness, and changed cells gain maximum level
                -

                -

                -

                Greenzone

                -


                -

                Since the Piano Roll interface provides the user with almost instant editing of the Input of any frame, it is also desirable to provide the ability to instantly view the game state at any given frame. This is accomplished by caching the data on all emulated game states.

                -


                -
                  -
                • The Greenzone is an array of data about the Output of the game, retrieved at the beginning of each frame. That is, the item #0 stores the game state before any emulation started, the item #1 stores the game state before emulating the second frame (the frame with number 000001), and so on. Besides the savestates the Greenzone stores the Lag Log that corresponds to the Input of the current movie. It's also theoretically possible to store other information.
                • -
                • The Greenzone starts with zeroth frame and has a lower boundary (head) – the frame number after which the Greenzone has no information about future game states (however, there may still be some information about the Lag of those frames).
                • -
                • The game data is collected into the Greenzone at the beginning of each frame (before emulation) in the following way: if the Greenzone array item with the number equal to the current frame is empty, or the position of the Greenzone head is smaller than the current frame number, then the array item is filled with information about the current game state (from emulator), and the Greenzone head moves forward if necessary.
                • -
                • To save some memory, the Greenzone is rarefied periodically, removing the savestates (but not the Lag Log data) of some early frames that are left too far from the Playback cursor. For details, see Program Customization.
                • -
                • All the Greenzone data together with the Lag Log is saved and loaded from the project file. After loading the project, Taseditor restores the Playback cursor state using the Greenzone.
                • -
                • Any change of the current movie Input forces the Greenzone remove the savestates of all frames after the first edited frame, not including the frame. This is accomplished by reducing the position of the Greenzone head and removing the outdated information from an array of savestates (but without freeing the memory, because the place of the old savestates will soon be taken by the new data of about the same size).
                • -
                • The Playback cursor must always be is inside the Greenzone, in order to avoid displaying the irrelevant game states on the FCEUX screen. So the Greenzone truncation may also move the Playback cursor.
                • -
                • When creating a Bookmark, the savestate of the bookmarked frame and the whole Lag Log are copied into it. When loading this Bookmark, the Greenzone is first truncated (because of the Input change), but then the bookmarked savestate and the relevant part of the bookmarked Lag Log are restored, and the Greenzone head position is moved, if necessary.
                • -
                • The Greenzone data is used for coloring the Piano Roll lines and the Bookmarks List items. The Lag Log stores information independently from savestates stored in the Greenzone. Every item of the Lag Log can have one of the three possible values: LAG=YES, LAG=NO, LAG=DONTKNOW.
                • -
                • The lag information for the Lag Log is collected at the same time when collecting the current game state to the Greenzone. That is, before emulating the current frame. At this point the emulator has knowledge about the previous frame lag, so at the frame 000020 we can store the lag data to the cell 19. Also, during this time the AdjustLag operation can fire off and shift the entire following Input up or down. The Input is shifted up, if in the previous frame the Lag Log has LAG=YES, and the emulator says there was no lag in previous frame. The Input moves down if the Lag Log has LAG=NO in the previous frame, and the emulator says there was lag. Together with the Input this operation shifts all subsequent items of the Lag Log get, so that the red lines of the Piano Roll are still consistent with the shifted Input gaps.
                • +


                  +

                  Greenzone

                  +


                  +

                  Since the Piano Roll interface provides the user with almost instant editing of the Input of any frame, it is also desirable to provide the ability to instantly view the game state at any given frame. This is accomplished by caching the data on all emulated game states.

                  +


                  +
                    +
                  • The Greenzone is an array of data about the Output of the game, retrieved at the beginning of each frame. That is, the item #0 stores the game state before any emulation started, the item #1 stores the game state before emulating the second frame (the frame with number 000001), and so on. Besides the savestates the Greenzone stores the Lag Log that corresponds to the Input of the current movie. It's also theoretically possible to store other information.
                  • +
                  • The Greenzone starts with zeroth frame and has a lower boundary (head) – the frame number after which the Greenzone has no information about future game states (however, there may still be some information about the Lag of those frames).
                  • +
                  • The game data is collected into the Greenzone at the beginning of each frame (before emulation) in the following way: if the Greenzone array item with the number equal to the current frame is empty, or the position of the Greenzone head is smaller than the current frame number, then the array item is filled with information about the current game state (from emulator), and the Greenzone head moves forward if necessary.
                  • +
                  • To save some memory, the Greenzone is rarefied periodically, removing the savestates (but not the Lag Log data) of some early frames that are left too far from the Playback cursor. For details, see Program Customization.
                  • +
                  • All the Greenzone data together with the Lag Log is saved and loaded from the project file. After loading the project, Taseditor restores the Playback cursor state using the Greenzone.
                  • +
                  • Any change of the current movie Input forces the Greenzone remove the savestates of all frames after the first edited frame, not including the frame. This is accomplished by reducing the position of the Greenzone head and removing the outdated information from an array of savestates (but without freeing the memory, because the place of the old savestates will soon be taken by the new data of about the same size).
                  • +
                  • The Playback cursor must always be is inside the Greenzone, in order to avoid displaying the irrelevant game states on the FCEUX screen. So the Greenzone truncation may also move the Playback cursor.
                  • +
                  • When creating a Bookmark, the savestate of the bookmarked frame and the whole Lag Log are copied into it. When loading this Bookmark, the Greenzone is first truncated (because of the Input change), but then the bookmarked savestate and the relevant part of the bookmarked Lag Log are restored, and the Greenzone head position is moved, if necessary.
                  • +
                  • The Greenzone data is used for coloring the Piano Roll lines and the Bookmarks List items. The Lag Log stores information independently from savestates stored in the Greenzone. Every item of the Lag Log can have one of the three possible values: LAG=YES, LAG=NO, LAG=DONTKNOW.
                  • +
                  • The lag information for the Lag Log is collected at the same time when collecting the current game state to the Greenzone. That is, before emulating the current frame. At this point the emulator has knowledge about the previous frame lag, so at the frame 000020 we can store the lag data to the cell 19. Also, during this time the AdjustLag operation can fire off and shift the entire following Input up or down. The Input is shifted up, if in the previous frame the Lag Log has LAG=YES, and the emulator says there was no lag in previous frame. The Input moves down if the Lag Log has LAG=NO in the previous frame, and the emulator says there was lag. Together with the Input this operation shifts all subsequent items of the Lag Log get, so that the red lines of the Piano Roll are still consistent with the shifted Input gaps.
                  -

                  -

                  -

                  Playback

                  -


                  -

                  The Playback is a meeting of all functions used for watching the game Output (the game state).

                  -


                  -
                    -
                  • The main attribute of the Playback is the "currently played movie frame", the frame whose screenshot is displayed at the emulator window at the moment. This frame corresponds to the light-blue line in the Piano Roll, which is called Playback cursor. Since the Playback cursor is tied to the state of the emulated game, you can use it not only as an indicator, but as a control too. E.g. to see the frame of interest on the FCEUX screen, you need to put the Playback cursor to the line with that frame number. There are many ways to do this.
                  • -
                  • When the user sends the Playback cursor on a frame contained in the Greenzone, the emulated game state is recovered from the corresponding savestate. Since there was no emulation in this case, Taseditor has to simulate the events "frame boundary" and "frame begin"/"frame end", so that the respective Lua functions could fire off.
                  • -
                  • When the user sends the Playback cursor on a frame outside the Greenzone, Taseditor restores the game state from the nearest preceding frame that has the Greenzone savestate, and then starts seeking to the desired frame. "Seeking" is the emulation which automatically stops when the target frame is reached. When the Playback is seeking, a copy of the light-blue cursor flashes at the target frame in the Piano Roll.
                  • -
                  • Seeking is based on the following assumption. Since the emulator provides determinism, the game state for any frame is guaranteed to be obtained by using the initial game state (the movie beginning state) and the Input of the movie. Moreover, you can get the required state using the state for any previous frame (any Greenzone savestate) and the Input of the movie.
                  • -
                  • The seeking process is indicated by the progressbar, in order to let the user estimate the waiting time if seeking takes too long. When there is no seeking, the progressbar is full during pause and empty during emulation.
                  • -
                  • The seeking can be done at the highest possible emulation speed. In this case the seeking will be finished instantly (for relatively small segments).
                  • -
                  • In many cases it is useful to automatically stop emulation at the last frame of the movie Input. The Autopause at the end of Movie option serves for this. When the emulator is paused, if the Playback cursor is not on the last movie frame, the Playback sets the "automatic stop" flag. And if the user releases the pause, the Playback automatically stops when it reaches the last movie frame. Thanks to it, the Playback cursor will not run away when the pause is released.
                  • -
                  • In most cases the user does not want to automatically scroll the Piano Roll after the Playback cursor when the cursor moves itself. But for the cases when it is needed, there is the "Follow cursor" checkbox.
                  • +


                    +

                    Playback

                    +


                    +

                    The Playback is a meeting of all functions used for watching the game Output (the game state).

                    +


                    +
                      +
                    • The main attribute of the Playback is the "currently played movie frame", the frame whose screenshot is displayed at the emulator window at the moment. This frame corresponds to the light-blue line in the Piano Roll, which is called Playback cursor. Since the Playback cursor is tied to the state of the emulated game, you can use it not only as an indicator, but as a control too. E.g. to see the frame of interest on the FCEUX screen, you need to put the Playback cursor to the line with that frame number. There are many ways to do this.
                    • +
                    • When the user sends the Playback cursor on a frame contained in the Greenzone, the emulated game state is recovered from the corresponding savestate. Since there was no emulation in this case, Taseditor has to simulate the events "frame boundary" and "frame begin"/"frame end", so that the respective Lua functions could fire off.
                    • +
                    • When the user sends the Playback cursor on a frame outside the Greenzone, Taseditor restores the game state from the nearest preceding frame that has the Greenzone savestate, and then starts seeking to the desired frame. "Seeking" is the emulation which automatically stops when the target frame is reached. When the Playback is seeking, a copy of the light-blue cursor flashes at the target frame in the Piano Roll.
                    • +
                    • Seeking is based on the following assumption. Since the emulator provides determinism, the game state for any frame is guaranteed to be obtained by using the initial game state (the movie beginning state) and the Input of the movie. Moreover, you can get the required state using the state for any previous frame (any Greenzone savestate) and the Input of the movie.
                    • +
                    • The seeking process is indicated by the progressbar, in order to let the user estimate the waiting time if seeking takes too long. When there is no seeking, the progressbar is full during pause and empty during emulation.
                    • +
                    • The seeking can be done at the highest possible emulation speed. In this case the seeking will be finished instantly (for relatively small segments).
                    • +
                    • In many cases it is useful to automatically stop emulation at the last frame of the movie Input. The Autopause at the end of Movie option serves for this. When the emulator is paused, if the Playback cursor is not on the last movie frame, the Playback sets the "automatic stop" flag. And if the user releases the pause, the Playback automatically stops when it reaches the last movie frame. Thanks to it, the Playback cursor will not run away when the pause is released.
                    • +
                    • In most cases the user does not want to automatically scroll the Piano Roll after the Playback cursor when the cursor moves itself. But for the cases when it is needed, there is the "Follow cursor" checkbox.
                    -

                    -

                    -

                    Green arrow

                    -


                    -

                    When making speedruns, TASer is trying to beat his record on each segment. In most cases the optimality criterion is the number of frame where the target event of the segment occurs. To detect the frame, TASer moves the Playback cursor while watching the FCEUX screen, and stops this manual search when he detects the beginning of the event of interest. Then the Playback cursor is usually left at this frame, and the TASer starts to change the Input on the segment (above the Playback cursor), hoping to improve the old approach and get the same event at an earlier frame.

                    -

                    While changing Input, the Greenzone becomes truncated and the Playback cursor jumps up. When the TASer believes that the Input was changed enough, he starts checking the game Output in order to determine at which frame the target event occurs now. For this, he moves the Playback cursor again while watching the FCEUX screen.

                    -

                    To conclude an improvement, the TASer needs to compare the old frame number (detected last time) and the new number, detected just recently. Taseditor visualizes this data to the user, so that he doesn't need to keep the numbers in mind. The new number is indicated by the Playback cursor, the old number is shown by the green arrow.

                    -


                    -
                      -
                    • Thus the actual name of the green arrow is "last position of the Playback cursor".
                    • -
                    • The more universal replacement of the green arrow would be Bookmarks and Markers that can be set manually.
                    • -
                    • The icon of the green arrow appears in the icons column of the Piano Roll. When drawing icons in Piano Roll, the green arrow has priority over the blue arrow (the Playback cursor icon), since the position of the blue cursor can be defined by the other columns.
                    • -
                    • The green arrow appears on the frame of the Playback cursor at the moment of Greenzone truncation. And it remains on that frame until the user performs the following sequence of actions:
                    • +


                      +

                      Green arrow

                      +


                      +

                      When making speedruns, TASer is trying to beat his record on each segment. In most cases the optimality criterion is the number of frame where the target event of the segment occurs. To detect the frame, TASer moves the Playback cursor while watching the FCEUX screen, and stops this manual search when he detects the beginning of the event of interest. Then the Playback cursor is usually left at this frame, and the TASer starts to change the Input on the segment (above the Playback cursor), hoping to improve the old approach and get the same event at an earlier frame.

                      +

                      While changing Input, the Greenzone becomes truncated and the Playback cursor jumps up. When the TASer believes that the Input was changed enough, he starts checking the game Output in order to determine at which frame the target event occurs now. For this, he moves the Playback cursor again while watching the FCEUX screen.

                      +

                      To conclude an improvement, the TASer needs to compare the old frame number (detected last time) and the new number, detected just recently. Taseditor visualizes this data to the user, so that he doesn't need to keep the numbers in mind. The new number is indicated by the Playback cursor, the old number is shown by the green arrow.

                      +


                      +
                        +
                      • Thus the actual name of the green arrow is "last position of the Playback cursor".
                      • +
                      • The more universal replacement of the green arrow would be Bookmarks and Markers that can be set manually.
                      • +
                      • The icon of the green arrow appears in the icons column of the Piano Roll. When drawing icons in Piano Roll, the green arrow has priority over the blue arrow (the Playback cursor icon), since the position of the blue cursor can be defined by the other columns.
                      • +
                      • The green arrow appears on the frame of the Playback cursor at the moment of Greenzone truncation. And it remains on that frame until the user performs the following sequence of actions:
                      -
                        -
                      1. emulate at least one frame (the user started viewing the segment)
                      2. -
                      3. truncate the Greenzone and jump up with the Playback cursor again
                      4. +
                          +
                        1. emulate at least one frame (the user started viewing the segment)
                        2. +
                        3. truncate the Greenzone and jump up with the Playback cursor again
                        -
                          -
                        • Thus the green arrow will not change its position when the Greenzone is truncated twice in a row without an emulation between (e. g. the TASer changed Input on the frame 90 and then on the frame 80, but the green arrow remains on the frame 100).
                        • -
                        • Also, the green arrow does not change its position when the Greenzone is truncated during seeking, granted that the emulator is unpaused at the moment.
                        • -
                        • The green arrow does not change its position during operations AdjustLag, Branch, Record.
                        • -
                        • When you press the middle mouse button, the Playback starts seeking to the green arrow, if the arrow is outside the Greenzone. But if the arrow is inside the Greenzone, it means the current segment has been already watched, and the automatic pause on the green arrow is not needed anymore.
                        • +
                            +
                          • Thus the green arrow will not change its position when the Greenzone is truncated twice in a row without an emulation between (e. g. the TASer changed Input on the frame 90 and then on the frame 80, but the green arrow remains on the frame 100).
                          • +
                          • Also, the green arrow does not change its position when the Greenzone is truncated during seeking, granted that the emulator is unpaused at the moment.
                          • +
                          • The green arrow does not change its position during operations AdjustLag, Branch, Record.
                          • +
                          • When you press the middle mouse button, the Playback starts seeking to the green arrow, if the arrow is outside the Greenzone. But if the arrow is inside the Greenzone, it means the current segment has been already watched, and the automatic pause on the green arrow is not needed anymore.
                          -

                          -

                          -

                          Auto-restore last position

                          -


                          -

                          When making any TAS, the optimality criterion may be either the game state on a certain frame, or the sequence of events on the segment. TASer watches the segment and leaves the Playback cursor on the last frame of the segment, then he changes the segment Input and watches the segment again, stopping the Playback cursor on the same frame as last time. TASer makes the conclusion about the improvement either while watching the segment events, or after stopping the emulation and evaluating the properties of the final frame.

                          -

                          That process can be automated by auto-starting the seeking to the green arrow after every Greenzone truncation. The "Auto-restore last position" checkbox serves for this purpose.

                          -


                          -
                            -
                          • When the checkbox is enabled, the Playback starts seeking to the green arrow right after the Greenzone truncation.
                          • -
                          • If the Greenzone was truncated during seeking, the original seeking will be resumed without changing the target frame. But if the seeking was paused at the moment of the Greenzone truncation, the original seeking is canceled and a new seeking will start, targeting the green arrow. The implication is that if TASer did not wait for the finish of seeking, and instead he paused the emulator and started to change the Input on the current segment, then TASer has focused on a subsegment, so the further auto-restore should run only for this subsegment.
                          • -
                          • Auto-restoring does not start during operations AdjustLag, Branch, Record. When the AdjustLag operation fires off, the movie playing is not affected.
                          • +


                            +

                            Auto-restore last position

                            +


                            +

                            When making any TAS, the optimality criterion may be either the game state on a certain frame, or the sequence of events on the segment. TASer watches the segment and leaves the Playback cursor on the last frame of the segment, then he changes the segment Input and watches the segment again, stopping the Playback cursor on the same frame as last time. TASer makes the conclusion about the improvement either while watching the segment events, or after stopping the emulation and evaluating the properties of the final frame.

                            +

                            That process can be automated by auto-starting the seeking to the green arrow after every Greenzone truncation. The "Auto-restore last position" checkbox serves for this purpose.

                            +


                            +
                              +
                            • When the checkbox is enabled, the Playback starts seeking to the green arrow right after the Greenzone truncation.
                            • +
                            • If the Greenzone was truncated during seeking, the original seeking will be resumed without changing the target frame. But if the seeking was paused at the moment of the Greenzone truncation, the original seeking is canceled and a new seeking will start, targeting the green arrow. The implication is that if TASer did not wait for the finish of seeking, and instead he paused the emulator and started to change the Input on the current segment, then TASer has focused on a subsegment, so the further auto-restore should run only for this subsegment.
                            • +
                            • Auto-restoring does not start during operations AdjustLag, Branch, Record. When the AdjustLag operation fires off, the movie playing is not affected.
                            -

                            -

                            -

                            Multitrack Recorder

                            -


                            -

                            The Recorder is a meeting of all functions for editing Input on the frame pointed by the Playback cursor. The Recorder provides TASer with the second way to edit Input – by recording.

                            -


                            -
                              -
                            • Multitracking allows TASer to change the data of only one selected joypad in Recording mode, leaving the other joypads data on the same frames intact. For details, see Toolbox.
                            • -
                            • When Recording mode is on, at the beginning of every frame the emulator polls virtual joypads and writes the data to the current movie. Then it immediately passes control to the Recorder.
                            • -
                            • Recorder:
                            • +


                              +

                              Multitrack Recorder

                              +


                              +

                              The Recorder is a meeting of all functions for editing Input on the frame pointed by the Playback cursor. The Recorder provides TASer with the second way to edit Input – by recording.

                              +


                              +
                                +
                              • Multitracking allows TASer to change the data of only one selected joypad in Recording mode, leaving the other joypads data on the same frames intact. For details, see Toolbox.
                              • +
                              • When Recording mode is on, at the beginning of every frame the emulator polls virtual joypads and writes the data to the current movie. Then it immediately passes control to the Recorder.
                              • +
                              • Recorder:
                              -
                                -
                              • uses the data from the movie (from the frame under the Playback cursor) as newly recorded data, or (if recording the pattern, and "no presses" need to be recorded now) uses nil as the newly recorded data
                              • -
                              • compares the newly recorded data to the old data stored in the History Log
                              • -
                              • imposes the filter over the changes, according to the currently selected multitracking mode
                              • -
                              • selectively combines old and new data, according to the "Superimpose" checkbox
                              • -
                              • saves the resultant changes to the current movie
                              • -
                              • calls the History Log to let it create a new item and then truncates the Greenzone
                              • -
                              • returns control to the emulator
                              • +
                                  +
                                • uses the data from the movie (from the frame under the Playback cursor) as newly recorded data, or (if recording the pattern, and "no presses" need to be recorded now) uses nil as the newly recorded data
                                • +
                                • compares the newly recorded data to the old data stored in the History Log
                                • +
                                • imposes the filter over the changes, according to the currently selected multitracking mode
                                • +
                                • selectively combines old and new data, according to the "Superimpose" checkbox
                                • +
                                • saves the resultant changes to the current movie
                                • +
                                • calls the History Log to let it create a new item and then truncates the Greenzone
                                • +
                                • returns control to the emulator
                                -
                                  -
                                • Emulator returns the current movie data (from the frame under the Playback cursor) to virtual joypads, in order to use the data for the frame emulation. Also, at this moment the emulator executes the recorded commands (reset, etc.).
                                • -
                                • Each frame, the Recorder gets information from the emulator about the currently pressed buttons of virtual joypads and prepares certain information for the Piano Roll, the information about which columns in the Piano Roll Header should glow green. For example, if you have selected the "2P" radiobutton and checked the "Use 1P keys for all single Recordings", that means when you press A on the first joypad, the Piano Roll Header will highlight the "A" symbol of the second joypad. And if the A button wasn't held in previous frame, the Recorder considers this in accordance with the "Use Input keys for Column Set" checkbox.
                                • +
                                    +
                                  • Emulator returns the current movie data (from the frame under the Playback cursor) to virtual joypads, in order to use the data for the frame emulation. Also, at this moment the emulator executes the recorded commands (reset, etc.).
                                  • +
                                  • Each frame, the Recorder gets information from the emulator about the currently pressed buttons of virtual joypads and prepares certain information for the Piano Roll, the information about which columns in the Piano Roll Header should glow green. For example, if you have selected the "2P" radiobutton and checked the "Use 1P keys for all single Recordings", that means when you press A on the first joypad, the Piano Roll Header will highlight the "A" symbol of the second joypad. And if the A button wasn't held in previous frame, the Recorder considers this in accordance with the "Use Input keys for Column Set" checkbox.
                                  -

                                  -

                                  -

                                  Lua automation

                                  -


                                  -

                                  Lua allows the user to expand Taseditor capabilities, in particular, it provides the TASer with the third way to edit Input – by automatic generation.

                                  -


                                  -
                                    -
                                  • Lua interpreter calls the appropriate Taseditor function not directly but through Taseditor's gateway (taseditor_lua).
                                  • -
                                  • When some function from the "taseditor" library fires off, Lua interpreter takes the arguments data from the stack, converts it to a format accepted by Taseditor's gateway, and sends it to the appropriate function of the Lua gateway of Taseditor.
                                  • -
                                  • The gateway calls the appropriate functions of Taseditor and sends the result back to the Lua interpreter.
                                  • -
                                  • Lua interpreter puts the returned data to the stack, converting the data to a format accepted by Lua code if necessary.
                                  • -
                                  • The functions submitinputchange(),  submitinsertframes() and submitdeleteframes() do not cause immediate change of the movie data, but only create an entry in the array of the postponed jobs, stored in Taseditor's Lua gateway. All the postponed jobs are executed when the applyinputchanges() function is called. Thanks to this, a Lua script can apply many changes to the movie at once, creating only one item in the History Log.
                                  • +


                                    +

                                    Lua automation

                                    +


                                    +

                                    Lua allows the user to expand Taseditor capabilities, in particular, it provides the TASer with the third way to edit Input – by automatic generation.

                                    +


                                    +
                                      +
                                    • Lua interpreter calls the appropriate Taseditor function not directly but through Taseditor's gateway (taseditor_lua).
                                    • +
                                    • When some function from the "taseditor" library fires off, Lua interpreter takes the arguments data from the stack, converts it to a format accepted by Taseditor's gateway, and sends it to the appropriate function of the Lua gateway of Taseditor.
                                    • +
                                    • The gateway calls the appropriate functions of Taseditor and sends the result back to the Lua interpreter.
                                    • +
                                    • Lua interpreter puts the returned data to the stack, converting the data to a format accepted by Lua code if necessary.
                                    • +
                                    • The functions submitinputchange(),  submitinsertframes() and submitdeleteframes() do not cause immediate change of the movie data, but only create an entry in the array of the postponed jobs, stored in Taseditor's Lua gateway. All the postponed jobs are executed when the applyinputchanges() function is called. Thanks to this, a Lua script can apply many changes to the movie at once, creating only one item in the History Log.
                                    -

                                    -

                                    -

                                    Bookmarks and branches

                                    -


                                    -

                                    Bookmarks are a specialized alternative to Markers. And branches are needed to store several movies in a single project. So, to simplify the creation and navigation through branches, they are assigned to Bookmarks, by analogy with the traditional savestates.

                                    -


                                    -
                                      -
                                    • A project can store up to 10 Bookmarks. This limitation is due to the number of the numeric keys on the keyboard. Also, such a restriction allows Taseditor to display basic information about all the Bookmarks at once, with no need for scrolling. In addition, the long-term experience of traditional TASing confirms that this number of slots for Bookmarks is enough for productive TASing.
                                    • -
                                    • A Bookmark can be set at any frame of the movie. Bookmarks will not disappear even when the movie is truncated. For example, if you set a Bookmark to the frame 1200 and then truncate the Input after frame 1000, a Bookmark will remain beyond the movie boundary, and if you jump to the Bookmark, the movie will expand to frame 1200.
                                    • -
                                    • Bookmarks are displayed in the Piano Roll as icons with corresponding digits (slot numbers). A Bookmark that corresponds the current movie branch is shown by the blue-colored digit, other Bookmarks are displayed by green digits.
                                    • -
                                    • A Bookmark can be set by pressing the corresponding hotkey (each slot has a dedicated hotkey for saving) or by right-click on the Bookmark slot. The Bookmark is set to the frame where the Playback cursor currently is. This frame number is stored in the Bookmark, and in the future you can always send the Playback cursor on that frame by clicking with the left mouse button over the Bookmark slot, or pressing the hotkey (each slot has a dedicated hotkey for jumping). "Jump to Bookmark" is not an operation, because no change is made to the movie.
                                    • -
                                    • When setting a Bookmark, Taseditor checks whether the newly saved data differs from the data already contained in this Bookmark slot. If there's no difference, the Bookmark operation is not performed.
                                    • -
                                    • In addition to storing the frame number, all movie data is also stored in the Bookmark slot (Input type, Input, Hot Changes, Markers). In future, the current movie may be changed many times, but you can always return back to the state of the movie stored in this Bookmark.
                                    • -
                                    • In addition, each Bookmark also stores the screenshot of the FCEUX screen at the time of bookmarking, allowing you to quickly see the contents of the Bookmark without loading it. Also it stores a copy of one savestate from the Greenzone (on the bookmarked frame), allowing to immediately put the Playback cursor on the Bookmark frame after loading the branch.
                                    • -
                                    • After setting a Bookmark, the Bookmark becomes current (shown with a blue-colored digit), because its branch is closer to the current movie than the other branches.
                                    • -
                                    • Whenever the current movie is changed to a bookmarked branch, the Input change occurs, so the Greenzone is truncated after the first different frame. But thanks to the savestate stored inside the Bookmark, one savestate returns back to the Greenzone on the bookmarked frame. Therefore, when loading a Bookmark you always immediately move the Playback cursor to the bookmarked frame, while jumping to a Bookmark (without changing the movie) may require seeking.
                                    • -
                                    • All Bookmark operations (setting, jumping, loading) are executed only after the emulation of the current frame, even if the signal from the user comes in the middle of the frame.
                                    • -
                                    • To display the basic Bookmark data, Taseditor uses the Listview with disabled scrolling. The List contains 10 rows and 3 columns. When creating a new project, all 10 Bookmarks are empty, so the 2nd and the 3rd columns in the Bookmark List are empty.
                                    • -
                                    • The 1st column of the Bookmarks List displays the slot number that corresponds to the given line. The number is displayed the same way it is displayed in the Piano Roll – i.e. with digit icons of green or blue color. The numbering of slots goes in this order: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0. This order is necessary, so that user doesn't lose the association with the numeric keys on the keyboard.
                                    • -
                                    • The 2nd column of the Bookmarks List displays the bookmarked frame number.
                                    • -
                                    • The 3rd column of the Bookmarks List displays the real time when the Bookmark was created.
                                    • -
                                    • The Bookmarks List is divided in half with a vertical bar. The left side (which contains the 1st and the 2nd column of the List) is associated with bookmarking functionality of the Bookmarks. The right side (the 3rd column) is associated with branching functionality of the Bookmarks. The left side is displayed in a lighter shade, the right one – in the darker. Left-clicking on the left side means a jump to the Bookmark, and left-click on the right side is loading the branch of the Bookmark.
                                    • -
                                    • Bookmarks List lines are painted in colors, matching the bookmarked Piano Roll lines. For example, if the Bookmark is set on the frame 1000, and the Playback cursor is currently on that frame, this line will be drawn in light-blue color in the the Bookmarks List. This feature gives the user some additional information about the Bookmarks location in the movie.
                                    • -
                                    • Instead of constant viewing of the Bookmarks List, the user can switch to the Branches Tree. Switching is done by clicking on the caption above the Bookmarks List.
                                    • -
                                    • Branches Tree is a graphical representation of the relationship between the branches of all Bookmarks in the project. Bookmarks are usually set during the movie creation, so the later Bookmarks contain the branch the initial part of which coincides with earlier Bookmarks branches. For each Bookmark you can find the "parent" Bookmark, whose movie likely gave birth to this Bookmark movie. As a result, Bookmarks can be arranged in a hierarchical structure, the beginning of which is the root (shown as a cloudlet), that is a parent for Bookmarks that have no parent. Searching for Bookmarks parents re-occurs after every change in Bookmarks. The search is guided by numbers of the bookmarked frames, so the beginning of the hierarchy will contain the Bookmarks with the lowest frame number.
                                    • -
                                    • Markers contained in the Bookmarks do not affect the algorithm of searching for parents. The parent is found by comparing the Input.
                                    • -
                                    • When you set a Bookmark, it becomes current, and its contents are no different from the current movie. But after some editing of the movie it will become different from the current Bookmark, so the Branches Tree will show the fireball to report the difference. The fireball symbolizes the current movie, and the current Bookmark is always considered to be its parent. There's no real search for the best parent of the fireball, because such search would need to be done after every movie modification, and it would require comparing the current movie to the Input of each Bookmark, that is too resource-intensive.
                                    • -
                                    • Bookmarks in the Branches tree are displayed as digit icons (like in the Piano Roll). Current Bookmark is displayed as a blue-colored digit. Bookmarks relation is shown in thin lines. For the current Bookmark there is a sequence of the red lines that connect all the Bookmarks which will not change the current movie Input if you load the Bookmark (because at least up to the bookmarked frame the loaded Input will be the same as the Input stored in the current Bookmark). These red lines go from the cloudlet to the current Bookmark or even further – to the heirs of the current Bookmark (if the current Bookmark contains the same Input as these successors).
                                    • -
                                    • Due to how the Bookmarks are located in ascending order of bookmarked frame numbers, the sequence of the red lines can be interpreted as a timeline of the current movie. The cloudlet is the beginning of this timeline, by clicking on it the Playback cursor is sent to the beginning of the movie. The Bookmarks sitting on the red thread are the intermediate stages of that timeline, by clicking on them the Playback cursor is sent to the bookmarked frames. The fireball (if exists) is considered to be the end of the timeline, and when you click on it the Playback cursor is sent to the end of the movie.
                                    • -
                                    • Thus, any position of the Playback cursor can be projected onto this timeline by finding the two Bookmarks which contain the Playback cursor in between, and then converting the distance from frames to pixels. As a result, the current Playback cursor position is always displayed in the Branches Tree as a small blue triangle (similar to the Playback cursor icon in Piano Roll).
                                    • -
                                    • If you need to see the alternative timeline of any Bookmark. hover the mouse cursor over it (the timeline will be displayed by blue lines).
                                    • -
                                    • All Bookmarks data is saved and loaded from the project file. As for the Branches Tree, Taseditor only saves the cached data about the number of the first frame of difference in the Input for each pair of Bookmarks. Based on this data, Taseditor easily restores the hierarchy of parent relation between the Bookmarks. And if this data is not available, Taseditor will have to redo the comparison of Input.
                                    • +


                                      +

                                      Bookmarks and branches

                                      +


                                      +

                                      Bookmarks are a specialized alternative to Markers. And branches are needed to store several movies in a single project. So, to simplify the creation and navigation through branches, they are assigned to Bookmarks, by analogy with the traditional savestates.

                                      +


                                      +
                                        +
                                      • A project can store up to 10 Bookmarks. This limitation is due to the number of the numeric keys on the keyboard. Also, such a restriction allows Taseditor to display basic information about all the Bookmarks at once, with no need for scrolling. In addition, the long-term experience of traditional TASing confirms that this number of slots for Bookmarks is enough for productive TASing.
                                      • +
                                      • A Bookmark can be set at any frame of the movie. Bookmarks will not disappear even when the movie is truncated. For example, if you set a Bookmark to the frame 1200 and then truncate the Input after frame 1000, a Bookmark will remain beyond the movie boundary, and if you jump to the Bookmark, the movie will expand to frame 1200.
                                      • +
                                      • Bookmarks are displayed in the Piano Roll as icons with corresponding digits (slot numbers). A Bookmark that corresponds the current movie branch is shown by the blue-colored digit, other Bookmarks are displayed by green digits.
                                      • +
                                      • A Bookmark can be set by pressing the corresponding hotkey (each slot has a dedicated hotkey for saving) or by right-click on the Bookmark slot. The Bookmark is set to the frame where the Playback cursor currently is. This frame number is stored in the Bookmark, and in the future you can always send the Playback cursor on that frame by clicking with the left mouse button over the Bookmark slot, or pressing the hotkey (each slot has a dedicated hotkey for jumping). "Jump to Bookmark" is not an operation, because no change is made to the movie.
                                      • +
                                      • When setting a Bookmark, Taseditor checks whether the newly saved data differs from the data already contained in this Bookmark slot. If there's no difference, the Bookmark operation is not performed.
                                      • +
                                      • In addition to storing the frame number, all movie data is also stored in the Bookmark slot (Input type, Input, Hot Changes, Markers). In future, the current movie may be changed many times, but you can always return back to the state of the movie stored in this Bookmark.
                                      • +
                                      • In addition, each Bookmark also stores the screenshot of the FCEUX screen at the time of bookmarking, allowing you to quickly see the contents of the Bookmark without loading it. Also it stores a copy of one savestate from the Greenzone (on the bookmarked frame), allowing to immediately put the Playback cursor on the Bookmark frame after loading the branch.
                                      • +
                                      • After setting a Bookmark, the Bookmark becomes current (shown with a blue-colored digit), because its branch is closer to the current movie than the other branches.
                                      • +
                                      • Whenever the current movie is changed to a bookmarked branch, the Input change occurs, so the Greenzone is truncated after the first different frame. But thanks to the savestate stored inside the Bookmark, one savestate returns back to the Greenzone on the bookmarked frame. Therefore, when loading a Bookmark you always immediately move the Playback cursor to the bookmarked frame, while jumping to a Bookmark (without changing the movie) may require seeking.
                                      • +
                                      • All Bookmark operations (setting, jumping, loading) are executed only after the emulation of the current frame, even if the signal from the user comes in the middle of the frame.
                                      • +
                                      • To display the basic Bookmark data, Taseditor uses the Listview with disabled scrolling. The List contains 10 rows and 3 columns. When creating a new project, all 10 Bookmarks are empty, so the 2nd and the 3rd columns in the Bookmark List are empty.
                                      • +
                                      • The 1st column of the Bookmarks List displays the slot number that corresponds to the given line. The number is displayed the same way it is displayed in the Piano Roll – i.e. with digit icons of green or blue color. The numbering of slots goes in this order: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0. This order is necessary, so that user doesn't lose the association with the numeric keys on the keyboard.
                                      • +
                                      • The 2nd column of the Bookmarks List displays the bookmarked frame number.
                                      • +
                                      • The 3rd column of the Bookmarks List displays the real time when the Bookmark was created.
                                      • +
                                      • The Bookmarks List is divided in half with a vertical bar. The left side (which contains the 1st and the 2nd column of the List) is associated with bookmarking functionality of the Bookmarks. The right side (the 3rd column) is associated with branching functionality of the Bookmarks. The left side is displayed in a lighter shade, the right one – in the darker. Left-clicking on the left side means a jump to the Bookmark, and left-click on the right side is loading the branch of the Bookmark.
                                      • +
                                      • Bookmarks List lines are painted in colors, matching the bookmarked Piano Roll lines. For example, if the Bookmark is set on the frame 1000, and the Playback cursor is currently on that frame, this line will be drawn in light-blue color in the the Bookmarks List. This feature gives the user some additional information about the Bookmarks location in the movie.
                                      • +
                                      • Instead of constant viewing of the Bookmarks List, the user can switch to the Branches Tree. Switching is done by clicking on the caption above the Bookmarks List.
                                      • +
                                      • Branches Tree is a graphical representation of the relationship between the branches of all Bookmarks in the project. Bookmarks are usually set during the movie creation, so the later Bookmarks contain the branch the initial part of which coincides with earlier Bookmarks branches. For each Bookmark you can find the "parent" Bookmark, whose movie likely gave birth to this Bookmark movie. As a result, Bookmarks can be arranged in a hierarchical structure, the beginning of which is the root (shown as a cloudlet), that is a parent for Bookmarks that have no parent. Searching for Bookmarks parents re-occurs after every change in Bookmarks. The search is guided by numbers of the bookmarked frames, so the beginning of the hierarchy will contain the Bookmarks with the lowest frame number.
                                      • +
                                      • Markers contained in the Bookmarks do not affect the algorithm of searching for parents. The parent is found by comparing the Input.
                                      • +
                                      • When you set a Bookmark, it becomes current, and its contents are no different from the current movie. But after some editing of the movie it will become different from the current Bookmark, so the Branches Tree will show the fireball to report the difference. The fireball symbolizes the current movie, and the current Bookmark is always considered to be its parent. There's no real search for the best parent of the fireball, because such search would need to be done after every movie modification, and it would require comparing the current movie to the Input of each Bookmark, that is too resource-intensive.
                                      • +
                                      • Bookmarks in the Branches tree are displayed as digit icons (like in the Piano Roll). Current Bookmark is displayed as a blue-colored digit. Bookmarks relation is shown in thin lines. For the current Bookmark there is a sequence of the red lines that connect all the Bookmarks which will not change the current movie Input if you load the Bookmark (because at least up to the bookmarked frame the loaded Input will be the same as the Input stored in the current Bookmark). These red lines go from the cloudlet to the current Bookmark or even further – to the heirs of the current Bookmark (if the current Bookmark contains the same Input as these successors).
                                      • +
                                      • Due to how the Bookmarks are located in ascending order of bookmarked frame numbers, the sequence of the red lines can be interpreted as a timeline of the current movie. The cloudlet is the beginning of this timeline, by clicking on it the Playback cursor is sent to the beginning of the movie. The Bookmarks sitting on the red thread are the intermediate stages of that timeline, by clicking on them the Playback cursor is sent to the bookmarked frames. The fireball (if exists) is considered to be the end of the timeline, and when you click on it the Playback cursor is sent to the end of the movie.
                                      • +
                                      • Thus, any position of the Playback cursor can be projected onto this timeline by finding the two Bookmarks which contain the Playback cursor in between, and then converting the distance from frames to pixels. As a result, the current Playback cursor position is always displayed in the Branches Tree as a small blue triangle (similar to the Playback cursor icon in Piano Roll).
                                      • +
                                      • If you need to see the alternative timeline of any Bookmark. hover the mouse cursor over it (the timeline will be displayed by blue lines).
                                      • +
                                      • All Bookmarks data is saved and loaded from the project file. As for the Branches Tree, Taseditor only saves the cached data about the number of the first frame of difference in the Input for each pair of Bookmarks. Based on this data, Taseditor easily restores the hierarchy of parent relation between the Bookmarks. And if this data is not available, Taseditor will have to redo the comparison of Input.
                                      -

                                      -

                                      -

                                      Pop-up windows

                                      -


                                      -

                                      They are used to display the context-sensitive information that is needed only at certain moments of time.

                                      -


                                      -
                                        -
                                      • TAS Editor 1.0 has only two types of pop-ups: screenshots for Bookmarks and text descriptions for Bookmarks. Both windows pop up when the user is hovering the mouse cursor either over the right side of the Bookmarks List or over any Bookmark icon in the Branches Tree.
                                      • -
                                      • Both windows appear (with translucency) within about half a second after the mouse cursor was pointed to an active element. They disappear in the similar fashion after moving the cursor off the item.
                                      • -
                                      • You can turn off one or the other type of pop-ups in the settings.
                                      • -
                                      • The screenshot pop-up window displays a copy of the FCEUX screen made at the time of bookmarking. Depending on the HUD in Branch screenshots option, the image will be either raw emulated console screen or the console screen with the superimposed emulator on-screen display. Screenshots are used to quickly check the Bookmarks contents and to compare alternative strategies.
                                      • -
                                      • The description pop-up window displays a text field with the width equal to the width of the upper and lower edit fields. That text field shows the Marker Note text taken from the pointed Bookmark branch. The Marker is determined by the bookmarked frame number.
                                      • -
                                      • The screenshot window is displayed to the left from the Bookmarks section, the description window appears under the screenshot window.
                                      • -
                                      • When you drag the TAS Editor window, the pop-ups move along with it.
                                      • -
                                      • If the contents of the displayed Bookmark change while pop-up windows still display the old contents, the pop-up windows will be instantly updated.
                                      • +


                                        +

                                        Pop-up windows

                                        +


                                        +

                                        They are used to display the context-sensitive information that is needed only at certain moments of time.

                                        +


                                        +
                                          +
                                        • TAS Editor 1.0 has only two types of pop-ups: screenshots for Bookmarks and text descriptions for Bookmarks. Both windows pop up when the user is hovering the mouse cursor either over the right side of the Bookmarks List or over any Bookmark icon in the Branches Tree.
                                        • +
                                        • Both windows appear (with translucency) within about half a second after the mouse cursor was pointed to an active element. They disappear in the similar fashion after moving the cursor off the item.
                                        • +
                                        • You can turn off one or the other type of pop-ups in the settings.
                                        • +
                                        • The screenshot pop-up window displays a copy of the FCEUX screen made at the time of bookmarking. Depending on the HUD in Branch screenshots option, the image will be either raw emulated console screen or the console screen with the superimposed emulator on-screen display. Screenshots are used to quickly check the Bookmarks contents and to compare alternative strategies.
                                        • +
                                        • The description pop-up window displays a text field with the width equal to the width of the upper and lower edit fields. That text field shows the Marker Note text taken from the pointed Bookmark branch. The Marker is determined by the bookmarked frame number.
                                        • +
                                        • The screenshot window is displayed to the left from the Bookmarks section, the description window appears under the screenshot window.
                                        • +
                                        • When you drag the TAS Editor window, the pop-ups move along with it.
                                        • +
                                        • If the contents of the displayed Bookmark change while pop-up windows still display the old contents, the pop-up windows will be instantly updated.
                                        -

                                        -

                                        -

                                        History Log

                                        -


                                        -

                                        The logging of all significant changes of the project serves mainly for undo, as well as for visual tracking of the history.

                                        -


                                        -
                                          -
                                        • Each item of the History Log stores a full copy of current Input, Lag and Markers at the time of the item creation. Also, any item can store a backup copy of a Bookmark, if the item was created because of the Bookmark operation.
                                        • -
                                        • The data of each item is stored in memory in both compressed and uncompressed state. Uncompressed data is used during work, and its compressed version is saved in fm3 file. When creating a new item in History Log, the data of the item is only stored in an uncompressed form, but every half-second Taseditor goes through the History Log and creates a compressed version of the first found item without a compressed version. Thus, at the time of saving the project to disk, almost all History items already have compressed versions, and those that don't have it will be compressed during saving (which slows down the process of saving). When loading an fm3 file, the History Log is loaded in a compressed form, and is decompressed.
                                        • -
                                        • Using the History Log, Taseditor implements searching for the first changed frame after which the Greenzone should be truncated. Most operations work as follows:
                                        • +


                                          +

                                          History Log

                                          +


                                          +

                                          The logging of all significant changes of the project serves mainly for undo, as well as for visual tracking of the history.

                                          +


                                          +
                                            +
                                          • Each item of the History Log stores a full copy of current Input, Lag and Markers at the time of the item creation. Also, any item can store a backup copy of a Bookmark, if the item was created because of the Bookmark operation.
                                          • +
                                          • The data of each item is stored in memory in both compressed and uncompressed state. Uncompressed data is used during work, and its compressed version is saved in fm3 file. When creating a new item in History Log, the data of the item is only stored in an uncompressed form, but every half-second Taseditor goes through the History Log and creates a compressed version of the first found item without a compressed version. Thus, at the time of saving the project to disk, almost all History items already have compressed versions, and those that don't have it will be compressed during saving (which slows down the process of saving). When loading an fm3 file, the History Log is loaded in a compressed form, and is decompressed.
                                          • +
                                          • Using the History Log, Taseditor implements searching for the first changed frame after which the Greenzone should be truncated. Most operations work as follows:
                                          -
                                            -
                                          • Edit the current movie data.
                                          • -
                                          • Remember the minimum and maximum number of changed frame.
                                          • -
                                          • Call the History to register changes, passing the minimum and maximum frame as parameters, together with the operation code and other parameters.
                                          • +
                                              +
                                            • Edit the current movie data.
                                            • +
                                            • Remember the minimum and maximum number of changed frame.
                                            • +
                                            • Call the History to register changes, passing the minimum and maximum frame as parameters, together with the operation code and other parameters.
                                            -
                                              -
                                            • The History compares the contents of the current movie with the contents of the last item of the History Log. If the minimum frame is provided, the search begins from that frame, ignoring the previous movie contents (in order to speed up the work). Otherwise everything from the movie beginning is checked. If the maximum frame is set, then the search ends on that frame (but most operations do not pass the maximum frame, since, for example, an insertion of a blank frame shifts all subsequent Input, and we need to check everything up to the end of the movie).
                                            • -
                                            • Once the History detects the first difference between the Input/Markers of the current movie and the Input/Markers of the previous movie snapshot, it creates a new new item in the History Log and fills all its attributes.
                                            • -
                                            • If the differences were not found, it is believed that the operation did not affect the movie, and no change in the project is registered. For example, if you record the same buttonpresses over existing ones, the Record operation will not be registered.
                                            • -
                                            • Even if an operation didn't change Input/Markers, it could still shift Lag, so the History also compares Lag Logs and returns the first frame of difference.
                                            • -
                                            • For the Record operation, the History registers not only the frame number of the changed Input, but also the number of the joypad whose buttons were changed.
                                            • -
                                            • Consecutively added items for operations AdjustLag, Record, Set or Unset can be combined into one item of the History Log, to make it easier to roll back when necessary. The combining is done when the History is filling the attributes of the new History Log item. Instead of appending the item to the end of the Log, it replaces the last item by the new one.
                                            • -
                                            • After the registration of a new item, the History sends a signal to the Branches Tree (to spawn the fireball) and to the project manager (to add an asterisk to the window caption), and then exits, returning the number of the frame of the first difference found. If no difference was found, it returns -1.
                                            • +
                                                +
                                              • The History compares the contents of the current movie with the contents of the last item of the History Log. If the minimum frame is provided, the search begins from that frame, ignoring the previous movie contents (in order to speed up the work). Otherwise everything from the movie beginning is checked. If the maximum frame is set, then the search ends on that frame (but most operations do not pass the maximum frame, since, for example, an insertion of a blank frame shifts all subsequent Input, and we need to check everything up to the end of the movie).
                                              • +
                                              • Once the History detects the first difference between the Input/Markers of the current movie and the Input/Markers of the previous movie snapshot, it creates a new new item in the History Log and fills all its attributes.
                                              • +
                                              • If the differences were not found, it is believed that the operation did not affect the movie, and no change in the project is registered. For example, if you record the same buttonpresses over existing ones, the Record operation will not be registered.
                                              • +
                                              • Even if an operation didn't change Input/Markers, it could still shift Lag, so the History also compares Lag Logs and returns the first frame of difference.
                                              • +
                                              • For the Record operation, the History registers not only the frame number of the changed Input, but also the number of the joypad whose buttons were changed.
                                              • +
                                              • Consecutively added items for operations AdjustLag, Record, Set or Unset can be combined into one item of the History Log, to make it easier to roll back when necessary. The combining is done when the History is filling the attributes of the new History Log item. Instead of appending the item to the end of the Log, it replaces the last item by the new one.
                                              • +
                                              • After the registration of a new item, the History sends a signal to the Branches Tree (to spawn the fireball) and to the project manager (to add an asterisk to the window caption), and then exits, returning the number of the frame of the first difference found. If no difference was found, it returns -1.
                                              -
                                                -
                                              • Truncate the Greenzone after the first different frame. This number can be greater than the minimum number of the frame of the changes made by the operation. For example, if you set buttonpresses in all selected frames, the minimum frame will be the first selected frame, but the Greenzone will be truncated only after the frame where the button wasn't pressed before.
                                              • +
                                                  +
                                                • Truncate the Greenzone after the first different frame. This number can be greater than the minimum number of the frame of the changes made by the operation. For example, if you set buttonpresses in all selected frames, the minimum frame will be the first selected frame, but the Greenzone will be truncated only after the frame where the button wasn't pressed before.
                                                -
                                                  -
                                                • The History can be rolled back by jumping from the current History Log item to the previous one. It's possible to directly jump to any item of the History Log. Current movie and current Markers are recovered from the data contained in this item, and the item becomes current.
                                                • -
                                                • One of the attributes of each History item is the "key frame number". For most operations it's the frame number of the first difference. But for operations that shift Input it will be the number of the minimum frame.
                                                • -
                                                • When jumping through History Items, a purple pointer appears in the Piano Roll for half a second, focusing the user's attention on the keyframe. When you roll back (undo), the purple cursor points to the keyframe of the next item in History (relative to the current), when you redo, this cursor points to the keyframe of the current History item.
                                                • +
                                                    +
                                                  • The History can be rolled back by jumping from the current History Log item to the previous one. It's possible to directly jump to any item of the History Log. Current movie and current Markers are recovered from the data contained in this item, and the item becomes current.
                                                  • +
                                                  • One of the attributes of each History item is the "key frame number". For most operations it's the frame number of the first difference. But for operations that shift Input it will be the number of the minimum frame.
                                                  • +
                                                  • When jumping through History Items, a purple pointer appears in the Piano Roll for half a second, focusing the user's attention on the keyframe. When you roll back (undo), the purple cursor points to the keyframe of the next item in History (relative to the current), when you redo, this cursor points to the keyframe of the current History item.
                                                  -

                                                  -

                                                  -

                                                  Rerecord counter

                                                  -


                                                  -

                                                  By tradition, all TAS emulators keep track of rerecords used during the creation of a TAS. This number can be used to estimate the labor.

                                                  -


                                                  -
                                                    -
                                                  • The Rerecord counter is stored in the movie (and hence in an fm3 project file too). When creating a new movie (or a new project in Taseditor) the counter is reset to 0.
                                                  • -
                                                  • When TASing outside of Taseditor: the counter increments every time the TASer loads a savestate in the Recording mode, since he wants to change the Input on the previously watched segment of the movie. The counter does not increase when the TASer records Input for frames whose events he does not know.
                                                  • -
                                                  • When TASing in Taseditor: the counter increments every time the TASer changes the Input of a previously greenzoned segment of the movie. The counter does not increase when the TASer changes Input for frames that are beyond the Greenzone head.
                                                  • -
                                                  • Thus in both cases the emulator keeps track of how many times the TASer changed the known future. The counter does not increase when the TASer changes the future blindly, i.e. before watching the game events occurring at the frames he edits.
                                                  • -
                                                  • In old emulators the counter increases immediately when loading the savestate in the Recording mode, even before the TASer changes Input. Because of this, it is possible that the user repeatedly presses a load savestate hotkey (e.g. F1), and each time the counter will increase. In Taseditor the counter increments only when truncating the Greenzone, regardless of the navigation method. Therefore, at the first press of the F1 the counter will increase only if the branch of this Bookmark is different from the current movie, and the difference begins from a greenzoned frame. And the second press of the F1 will not increase the counter, because now the Bookmark branch does not differ from the current movie, and no Input change is happening.
                                                  • +


                                                    +

                                                    Rerecord counter

                                                    +


                                                    +

                                                    By tradition, all TAS emulators keep track of rerecords used during the creation of a TAS. This number can be used to estimate the labor.

                                                    +


                                                    +
                                                      +
                                                    • The Rerecord counter is stored in the movie (and hence in an fm3 project file too). When creating a new movie (or a new project in Taseditor) the counter is reset to 0.
                                                    • +
                                                    • When TASing outside of Taseditor: the counter increments every time the TASer loads a savestate in the Recording mode, since he wants to change the Input on the previously watched segment of the movie. The counter does not increase when the TASer records Input for frames whose events he does not know.
                                                    • +
                                                    • When TASing in Taseditor: the counter increments every time the TASer changes the Input of a previously greenzoned segment of the movie. The counter does not increase when the TASer changes Input for frames that are beyond the Greenzone head.
                                                    • +
                                                    • Thus in both cases the emulator keeps track of how many times the TASer changed the known future. The counter does not increase when the TASer changes the future blindly, i.e. before watching the game events occurring at the frames he edits.
                                                    • +
                                                    • In old emulators the counter increases immediately when loading the savestate in the Recording mode, even before the TASer changes Input. Because of this, it is possible that the user repeatedly presses a load savestate hotkey (e.g. F1), and each time the counter will increase. In Taseditor the counter increments only when truncating the Greenzone, regardless of the navigation method. Therefore, at the first press of the F1 the counter will increase only if the branch of this Bookmark is different from the current movie, and the difference begins from a greenzoned frame. And the second press of the F1 will not increase the counter, because now the Bookmark branch does not differ from the current movie, and no Input change is happening.
                                                    -

                                                    -

                                                    -

                                                    Modifier keys system

                                                    -


                                                    -

                                                    For a more intuitive keyboard control, Taseditor enforces a strict separation of modifier keys functions:

                                                    -


                                                    -
                                                      -
                                                    • Shift is associated with the movie Output, and specifically with the Playback cursor. Key combinations involving this key usually control the Playback cursor. If you quickly press Shift twice, the Piano Roll will automatically scroll to the Playback cursor.
                                                    • -
                                                    • Ctrl is associated with the movie Input, and specifically with the Selection cursor. Key combinations involving this key usually control the Selection. If you quickly press Ctrl twice, the Piano Roll will automatically scroll to the Selection cursor.
                                                    • -
                                                    • Alt is associated with patterns and alternating sequences, in particular, with gaps in these sequences.
                                                    • +


                                                      +

                                                      Modifier keys system

                                                      +


                                                      +

                                                      For a more intuitive keyboard control, Taseditor enforces a strict separation of modifier keys functions:

                                                      +


                                                      +
                                                        +
                                                      • Shift is associated with the movie Output, and specifically with the Playback cursor. Key combinations involving this key usually control the Playback cursor. If you quickly press Shift twice, the Piano Roll will automatically scroll to the Playback cursor.
                                                      • +
                                                      • Ctrl is associated with the movie Input, and specifically with the Selection cursor. Key combinations involving this key usually control the Selection. If you quickly press Ctrl twice, the Piano Roll will automatically scroll to the Selection cursor.
                                                      • +
                                                      • Alt is associated with patterns and alternating sequences, in particular, with gaps in these sequences.
                                                      -

                                                      -

                                                      -

                                                      Patterns

                                                      -


                                                      -

                                                      Prepared sequence of button states for a single button. See more in Advanced Features.

                                                      -


                                                      -
                                                        -
                                                      • Patterns are stored in an external text file in a format that can be edited in Notepad. The file format should be described in the file itself.
                                                      • -
                                                      • Each pattern must have its name, which will appear in the list of patterns.
                                                      • -
                                                      • Patterns are loaded from the file at the time of launching the TAS Editor.
                                                      • -
                                                      • TAS Editor 1.0 has no built-in Pattern editing, as the format is very simple and that feature is not too much in demand.
                                                      • -
                                                      • Input, Markers and even Selection can be set by pattern.
                                                      • -
                                                      • When you set a pattern, the current lag log can be taken into account or disregarded. More: Program Customization.
                                                      • +


                                                        +

                                                        Patterns

                                                        +


                                                        +

                                                        Prepared sequence of button states for a single button. See more in Advanced Features.

                                                        +


                                                        +
                                                          +
                                                        • Patterns are stored in an external text file in a format that can be edited in Notepad. The file format should be described in the file itself.
                                                        • +
                                                        • Each pattern must have its name, which will appear in the list of patterns.
                                                        • +
                                                        • Patterns are loaded from the file at the time of launching the TAS Editor.
                                                        • +
                                                        • TAS Editor 1.0 has no built-in Pattern editing, as the format is very simple and that feature is not too much in demand.
                                                        • +
                                                        • Input, Markers and even Selection can be set by pattern.
                                                        • +
                                                        • When you set a pattern, the current lag log can be taken into account or disregarded. More: Program Customization.
                                                        -

                                                        -

                                                        -

                                                        Crossing gaps

                                                        -


                                                        -

                                                        This is an additional method of quick navigation through the Piano Roll contents. It helps to visually track long sequences of a single button or Markers. Also it allows to move from a Bookmark to another Bookmark.

                                                        -


                                                        -
                                                          -
                                                        • Crossing gaps is the process of scrolling the Piano Roll vertically, triggered by rolling the mouse wheel while holding down Alt. The speed of rolling the wheel is irrelevant here, because the actual amount of scrolling is calculated individually based on the state of the Piano Roll cell near the mouse cursor. So only the direction of the wheel rolling is relevant (up or down).
                                                        • -
                                                        • Crossing gaps implies that the user wants to find the cell at a distance of more than one frame from the cell under the mouse cursor (otherwise there is no reason to use this feature, because you could simply move your mouse right above).
                                                        • -
                                                        • Thus, when the mouse wheel is scrolled up, this feature memorizes the value of the cell above the cell under the mouse cursor. Then it searches for a cell whose value is not equal to a given value. Search goes upwards from the cell above the cell under the mouse. If such a cell is successfully found, the Piano Roll scrolls up so that the mouse cursor is now pointing to the found cell. If the search reached the movie beginning, and the cell was not found, the Piano Roll does not scroll.
                                                        • -
                                                        • Similarly, when the mouse wheel is rolled down, this feature memorizes the value of the cell following the cell under the mouse. Then it searches for a cell whose value is not equal to the value. Search goes down from the cell following the cell under the mouse.
                                                        • -
                                                        • The memorized value is of a boolean type. E.g. the search considers all icons to have the same value (true), and all empty cells also have the same value (false).
                                                        • +


                                                          +

                                                          Crossing gaps

                                                          +


                                                          +

                                                          This is an additional method of quick navigation through the Piano Roll contents. It helps to visually track long sequences of a single button or Markers. Also it allows to move from a Bookmark to another Bookmark.

                                                          +


                                                          +
                                                            +
                                                          • Crossing gaps is the process of scrolling the Piano Roll vertically, triggered by rolling the mouse wheel while holding down Alt. The speed of rolling the wheel is irrelevant here, because the actual amount of scrolling is calculated individually based on the state of the Piano Roll cell near the mouse cursor. So only the direction of the wheel rolling is relevant (up or down).
                                                          • +
                                                          • Crossing gaps implies that the user wants to find the cell at a distance of more than one frame from the cell under the mouse cursor (otherwise there is no reason to use this feature, because you could simply move your mouse right above).
                                                          • +
                                                          • Thus, when the mouse wheel is scrolled up, this feature memorizes the value of the cell above the cell under the mouse cursor. Then it searches for a cell whose value is not equal to a given value. Search goes upwards from the cell above the cell under the mouse. If such a cell is successfully found, the Piano Roll scrolls up so that the mouse cursor is now pointing to the found cell. If the search reached the movie beginning, and the cell was not found, the Piano Roll does not scroll.
                                                          • +
                                                          • Similarly, when the mouse wheel is rolled down, this feature memorizes the value of the cell following the cell under the mouse. Then it searches for a cell whose value is not equal to the value. Search goes down from the cell following the cell under the mouse.
                                                          • +
                                                          • The memorized value is of a boolean type. E.g. the search considers all icons to have the same value (true), and all empty cells also have the same value (false).
                                                          -

                                                          -

                                                          -

                                                          Compact saving

                                                          -


                                                          -

                                                          The Taseditor project file is primarily designed to save the exact snapshot of the workflow.

                                                          -

                                                          In order to use the same format for file sharing, the user should be able to selectively save data to the file. When you open such an fm3 file, the missing data is be replaced with default data.

                                                          -

                                                          For details, see Advanced Features and FM3 Format.

                                                          -

                                                          -

                                                          -

                                                          Autosave

                                                          -


                                                          -

                                                          As any office document, Taseditor project should to be saved to disk from time to time, even if you do not plan to exit the program. However, TASers are not accustomed to such habits, so it makes sense to save the project automatically, allowing the user to customize or disable this feature.

                                                          -

                                                          For details, see Program Customization.

                                                          -


                                                          -
                                                          -

                                                          -

                                                          -

                                                          Planned ideas

                                                          -


                                                          -

                                                          -

                                                          -

                                                          Output Log

                                                          -


                                                          -

                                                          This is the next stage of evolution of the Memory Watch tool. It's intended to watch the game data in a dynamic way, not just static. Similarly to the Lag Log, this feature will make analyzing the game Output  easier and more accurate.

                                                          -


                                                          -
                                                            -
                                                          • It is a significantly redesigned ListView, whose vertical scrolling is synchronized with the Piano Roll scrolling. Its height is equal to the height of the Piano Roll, and the number of rows is always equal to the number of Piano Roll lines. The number of columns depends on the needs of the user.
                                                          • -
                                                          • The user can flexibly change the width of the List by dragging the narrow border between it and the Piano Roll, thus changing the Piano Roll width as well, so their total width is always the same. You can also swap the List and the Piano Roll, or even completely disable the display of the Output Log. When you disable the Log display, the Piano Roll extends to take up the free up space, just as in TAS Editor 1.0. Note that hiding the Log does not disable logging of data.
                                                          • -
                                                          • The List Header displays the names of logged cells. You can add and remove columns, change names, change places and change the columns width. When you create a new project, the Output Log has no columns, and, accordingly, nothing is logged.
                                                          • -
                                                          • The rows of the List display the values of the cells. The values are saved from the game state on the appropriate movie frame. The List lines are painted with the same colors as the corresponding Piano Roll lines. When you select a line in the Piano Roll, the respective Log lines are selected too.
                                                          • -
                                                          • In addition to the RAM cells, it's necessary to implement Lua variables logging. For example, to provide Lua-scripts with a read/write-access to a dozen of Taseditor's int-variables and allow the user to log any variable from the dozen.
                                                          • -
                                                          • In addition, in the future a column with screenshots of the game (or selected rectangular area of the game screen) should be added. The displayed size of the screenshots will depend on the current width of the screenshots column, and as a result, the screenshots will not appear on each line of the Log, but on every few lines, even though the screenshot capturing is done every frame.
                                                          • -
                                                          • All logged data is stored in the Greenzone, along with the Lag Log. When adding a RAM cell, an automatic filling of the entire column is possible (Taseditor runs through all Greenzone savestates, unpacks them and takes the value of the saved copy of RAM). When you add a Lua variable, the cell values are unknown (blank cells in the list), and to fill them you need to re-emulate the movie with the Lua-script running.
                                                          • -
                                                          • When truncating the Greenzone, the old data that has become outdated will not be removed, but will appear in less bright color, until the new data takes its place. Also, when savestates are removed from the Greenzone tail, the Log data remains intact and is shown in the normal color.
                                                          • -
                                                          • It should allow flexible coloring of cells, for example, highlighting the same values in the Selection, highlighting the desired values, automatic color change when the value changes, automatic indication when certain value is hit, etc.
                                                          • -
                                                          • Lua scripts may read any Greenzone data using Taseditor API.
                                                          • -
                                                          • The accelerators Shift + Right / Shift + Left will now scroll horizontally not the Piano Roll, but the Output Log. Scrolling is done by whole columns.
                                                          • -
                                                          • It is also necessary to implement the new methods of navigation through the movie, depending on the cells values. For example, by using the Alt key and the wheel you can cross gaps in the List to find the nearest unequal or equal value.
                                                          • +


                                                            +

                                                            Compact saving

                                                            +


                                                            +

                                                            The Taseditor project file is primarily designed to save the exact snapshot of the workflow.

                                                            +

                                                            In order to use the same format for file sharing, the user should be able to selectively save data to the file. When you open such an fm3 file, the missing data is be replaced with default data.

                                                            +

                                                            For details, see Advanced Features and FM3 Format.

                                                            +


                                                            +

                                                            Autosave

                                                            +


                                                            +

                                                            As any office document, Taseditor project should to be saved to disk from time to time, even if you do not plan to exit the program. However, TASers are not accustomed to such habits, so it makes sense to save the project automatically, allowing the user to customize or disable this feature.

                                                            +

                                                            For details, see Program Customization.

                                                            +


                                                            +
                                                            +


                                                            +

                                                            Planned ideas

                                                            +


                                                            +


                                                            +

                                                            Output Log

                                                            +


                                                            +

                                                            This is the next stage of evolution of the Memory Watch tool. It's intended to watch the game data in a dynamic way, not just static. Similarly to the Lag Log, this feature will make analyzing the game Output  easier and more accurate.

                                                            +


                                                            +
                                                              +
                                                            • It is a significantly redesigned ListView, whose vertical scrolling is synchronized with the Piano Roll scrolling. Its height is equal to the height of the Piano Roll, and the number of rows is always equal to the number of Piano Roll lines. The number of columns depends on the needs of the user.
                                                            • +
                                                            • The user can flexibly change the width of the List by dragging the narrow border between it and the Piano Roll, thus changing the Piano Roll width as well, so their total width is always the same. You can also swap the List and the Piano Roll, or even completely disable the display of the Output Log. When you disable the Log display, the Piano Roll extends to take up the free up space, just as in TAS Editor 1.0. Note that hiding the Log does not disable logging of data.
                                                            • +
                                                            • The List Header displays the names of logged cells. You can add and remove columns, change names, change places and change the columns width. When you create a new project, the Output Log has no columns, and, accordingly, nothing is logged.
                                                            • +
                                                            • The rows of the List display the values of the cells. The values are saved from the game state on the appropriate movie frame. The List lines are painted with the same colors as the corresponding Piano Roll lines. When you select a line in the Piano Roll, the respective Log lines are selected too.
                                                            • +
                                                            • In addition to the RAM cells, it's necessary to implement Lua variables logging. For example, to provide Lua-scripts with a read/write-access to a dozen of Taseditor's int-variables and allow the user to log any variable from the dozen.
                                                            • +
                                                            • In addition, in the future a column with screenshots of the game (or selected rectangular area of the game screen) should be added. The displayed size of the screenshots will depend on the current width of the screenshots column, and as a result, the screenshots will not appear on each line of the Log, but on every few lines, even though the screenshot capturing is done every frame.
                                                            • +
                                                            • All logged data is stored in the Greenzone, along with the Lag Log. When adding a RAM cell, an automatic filling of the entire column is possible (Taseditor runs through all Greenzone savestates, unpacks them and takes the value of the saved copy of RAM). When you add a Lua variable, the cell values are unknown (blank cells in the list), and to fill them you need to re-emulate the movie with the Lua-script running.
                                                            • +
                                                            • When truncating the Greenzone, the old data that has become outdated will not be removed, but will appear in less bright color, until the new data takes its place. Also, when savestates are removed from the Greenzone tail, the Log data remains intact and is shown in the normal color.
                                                            • +
                                                            • It should allow flexible coloring of cells, for example, highlighting the same values in the Selection, highlighting the desired values, automatic color change when the value changes, automatic indication when certain value is hit, etc.
                                                            • +
                                                            • Lua scripts may read any Greenzone data using Taseditor API.
                                                            • +
                                                            • The accelerators Shift + Right / Shift + Left will now scroll horizontally not the Piano Roll, but the Output Log. Scrolling is done by whole columns.
                                                            • +
                                                            • It is also necessary to implement the new methods of navigation through the movie, depending on the cells values. For example, by using the Alt key and the wheel you can cross gaps in the List to find the nearest unequal or equal value.
                                                            -

                                                            -

                                                            -

                                                            Minimap

                                                            -


                                                            -

                                                            Graphically displays the entire movie in TAS Editor window – Greenzone, Lag, Playback cursor, Selection, Markers, Bookmarks, Hot Changes, highlighted Output Log values, etc. Provides the user with an instant image of the current project, which lacks details but completely fits on the screen. Also improves navigation.

                                                            -


                                                            -
                                                              -
                                                            • The Minimap is a rectangular bitmap canvas, whose height is equal to the height of the Piano Roll, and the width is 30 pixels (plus 10px for Bookmark icons). Can be positioned to the left or right from the Piano Roll and the Output Log.
                                                            • -
                                                            • The "View" menu item allows the user to customize the elements displayed on Minimap (set a tick near the desired items). You can also entirely disable the display of Minimap.
                                                            • -
                                                            • The Minimap does not store any data of the project. It is automatically redrawn in the specified interval of time (by default, once per second).
                                                            • -
                                                            • Markers are displayed as horizontal yellow lines on the left half of the Minimap. Each Marker line has the height of at least one pixel, so the Markers are not lost even on a small-scale Minimap (when the movie has a lot more frames than the height of the Minimap in pixels). The line width is 9px.
                                                            • -
                                                            • Hot Changes are displayed as horizontal lines of the corresponding color on the right side of the Minimap. Each line has the height of at least one pixel. The line width is 9px.
                                                            • -
                                                            • Bookmarks are displayed by corresponding icons to the left from the Minimap, and they take additional 10px. You can click these icons with left or right mouse button, the effect will be similar to clicking on the icon in the Branches Tree.
                                                            • -
                                                            • When the mouse cursor hovers over the Minimap, it displays the rectangular magnifying glass.
                                                            • -
                                                            • Left-click on the Minimap = instant scrolling of visible area of the Piano Roll to that place. You can then drag the visible area up/down by holding the right button.
                                                            • -
                                                            • Shift + left-click, or just right-click on the Minimap = Playback cursor navigation. You can then drag the Playback cursor by holding the right button.
                                                            • +


                                                              +

                                                              Minimap

                                                              +


                                                              +

                                                              Graphically displays the entire movie in TAS Editor window – Greenzone, Lag, Playback cursor, Selection, Markers, Bookmarks, Hot Changes, highlighted Output Log values, etc. Provides the user with an instant image of the current project, which lacks details but completely fits on the screen. Also improves navigation.

                                                              +


                                                              +
                                                                +
                                                              • The Minimap is a rectangular bitmap canvas, whose height is equal to the height of the Piano Roll, and the width is 30 pixels (plus 10px for Bookmark icons). Can be positioned to the left or right from the Piano Roll and the Output Log.
                                                              • +
                                                              • The "View" menu item allows the user to customize the elements displayed on Minimap (set a tick near the desired items). You can also entirely disable the display of Minimap.
                                                              • +
                                                              • The Minimap does not store any data of the project. It is automatically redrawn in the specified interval of time (by default, once per second).
                                                              • +
                                                              • Markers are displayed as horizontal yellow lines on the left half of the Minimap. Each Marker line has the height of at least one pixel, so the Markers are not lost even on a small-scale Minimap (when the movie has a lot more frames than the height of the Minimap in pixels). The line width is 9px.
                                                              • +
                                                              • Hot Changes are displayed as horizontal lines of the corresponding color on the right side of the Minimap. Each line has the height of at least one pixel. The line width is 9px.
                                                              • +
                                                              • Bookmarks are displayed by corresponding icons to the left from the Minimap, and they take additional 10px. You can click these icons with left or right mouse button, the effect will be similar to clicking on the icon in the Branches Tree.
                                                              • +
                                                              • When the mouse cursor hovers over the Minimap, it displays the rectangular magnifying glass.
                                                              • +
                                                              • Left-click on the Minimap = instant scrolling of visible area of the Piano Roll to that place. You can then drag the visible area up/down by holding the right button.
                                                              • +
                                                              • Shift + left-click, or just right-click on the Minimap = Playback cursor navigation. You can then drag the Playback cursor by holding the right button.
                                                              -

                                                              -

                                                              -

                                                              Virtual Joypad

                                                              -


                                                              -

                                                              An alternative way to enter Input. Very similar to modifying Input by clicking the Piano Roll Header, but is more visual and intuitive.

                                                              -


                                                              -
                                                                -
                                                              • The Virtual Joypad is a non-modal pop-up resizable window. Contents of the window are automatically resized when the window is resized.
                                                              • -
                                                              • The Virtual Joypad window appears under the mouse cursor when you right-click in the Piano Roll on the selected Input or on Input under the Playback cursor. In the settings you can disable the appearance of the Virtual Joypad under the cursor when you right click. Then you can leave the window in a convenient place on the desktop and move the mouse cursor back and forth from the Piano Roll to the Virtual Joypad.
                                                              • -
                                                              • By the window background color you can determine whether the Virtual Joypad currently displays the Input state in the Selection (dark blue), or under the Playback cursor (light-blue).
                                                              • -
                                                              • When the mouse cursor is moved out of the Virtual Joypad window, this window is either hidden automatically (if the "Hide on mouse leave" is checked) or left in place.
                                                              • -
                                                              • When you press the left mouse button over the inactive area of the window, the window dragging starts.
                                                              • -
                                                              • When you right-click anywhere in the window, it hides.
                                                              • -
                                                              • Various controls can be located inside the window – e.g. the buttons that correspond to the real joypad buttons. The buttons layout corresponds to the real prototype. By the buttons look you can determine whether the corresponding button in the Selection is pressed, released or partially pressed (this is for cases when more than one frame is Selected).
                                                              • -
                                                              • The window contents are automatically updated every time the Input is changed, or Selection is changed and the Virtual Joypad shows the Input in the Selection.
                                                              • -
                                                              • The Virtual Joypad reflects only the state of the single controller – the current controller, selected by a radiobutton in the Recorder section.
                                                              • -
                                                              • When you click on a button, it changes the Input of the current joypad. Pressed button becomes released, and released or partially pressed becomes pressed. The Input of all the selected frames or the frame under the Playback cursor changes accordingly.
                                                              • -
                                                              • In addition to the normal Input buttons, the Virtual Joypad may contain several macro-buttons. A click on a macro button will be similar to a few clicks on different normal buttons. This will allow to change the Input in the Selection even faster than before, for example, instead of three clicks on Up, Right, and B buttons, you can do one click on Macro1.
                                                              • -
                                                              • If you hold down Alt before clicking a Virtual Joypad button or a macro button, the Input will be set by pattern.
                                                              • -
                                                              • After implementing the Virtual Joypad we can change the principle of clicking on the Piano Roll Header. Instead of changing the Input, the click on the Header will select the appropriate columns in the Piano Roll.
                                                              • +


                                                                +

                                                                Virtual Joypad

                                                                +


                                                                +

                                                                An alternative way to enter Input. Very similar to modifying Input by clicking the Piano Roll Header, but is more visual and intuitive.

                                                                +


                                                                +
                                                                  +
                                                                • The Virtual Joypad is a non-modal pop-up resizable window. Contents of the window are automatically resized when the window is resized.
                                                                • +
                                                                • The Virtual Joypad window appears under the mouse cursor when you right-click in the Piano Roll on the selected Input or on Input under the Playback cursor. In the settings you can disable the appearance of the Virtual Joypad under the cursor when you right click. Then you can leave the window in a convenient place on the desktop and move the mouse cursor back and forth from the Piano Roll to the Virtual Joypad.
                                                                • +
                                                                • By the window background color you can determine whether the Virtual Joypad currently displays the Input state in the Selection (dark blue), or under the Playback cursor (light-blue).
                                                                • +
                                                                • When the mouse cursor is moved out of the Virtual Joypad window, this window is either hidden automatically (if the "Hide on mouse leave" is checked) or left in place.
                                                                • +
                                                                • When you press the left mouse button over the inactive area of the window, the window dragging starts.
                                                                • +
                                                                • When you right-click anywhere in the window, it hides.
                                                                • +
                                                                • Various controls can be located inside the window – e.g. the buttons that correspond to the real joypad buttons. The buttons layout corresponds to the real prototype. By the buttons look you can determine whether the corresponding button in the Selection is pressed, released or partially pressed (this is for cases when more than one frame is Selected).
                                                                • +
                                                                • The window contents are automatically updated every time the Input is changed, or Selection is changed and the Virtual Joypad shows the Input in the Selection.
                                                                • +
                                                                • The Virtual Joypad reflects only the state of the single controller – the current controller, selected by a radiobutton in the Recorder section.
                                                                • +
                                                                • When you click on a button, it changes the Input of the current joypad. Pressed button becomes released, and released or partially pressed becomes pressed. The Input of all the selected frames or the frame under the Playback cursor changes accordingly.
                                                                • +
                                                                • In addition to the normal Input buttons, the Virtual Joypad may contain several macro-buttons. A click on a macro button will be similar to a few clicks on different normal buttons. This will allow to change the Input in the Selection even faster than before, for example, instead of three clicks on Up, Right, and B buttons, you can do one click on Macro1.
                                                                • +
                                                                • If you hold down Alt before clicking a Virtual Joypad button or a macro button, the Input will be set by pattern.
                                                                • +
                                                                • After implementing the Virtual Joypad we can change the principle of clicking on the Piano Roll Header. Instead of changing the Input, the click on the Header will select the appropriate columns in the Piano Roll.
                                                                -

                                                                -

                                                                -

                                                                Selection improvement

                                                                -


                                                                -

                                                                TAS Editor 1.0 architecture is not designed to support the selection of Piano Roll columns, but in some situations it may be useful in TASing. For example, to clear the Input of the first joypad without clearing the second joypad Input. Or to shift the Input for one buttons without moving the rest buttons.

                                                                -

                                                                Besides, it's necessary to improve the process of painting the Selection, so that users will see the Piano Roll line color under the translucent Selection.

                                                                -


                                                                -
                                                                  -
                                                                • Selecting columns should be done like selecting rows – when you left-click on the Header of the corresponding Piano Roll column, the column is selected, and all other columns are deselected. If you hold down Ctrl before clicking the button, Selection of the rest columns will not disappear. If you hold down Shift, you will select the range of columns from the previous click place. If you hold down Alt, the columns selection will be set by pattern. And of course after clicking you can hold the left mouse button and stretch the selection horizontally.
                                                                • -
                                                                • Only Input columns can be selected. The Markers depend on the "Bind Markers to Input" setting.
                                                                • -
                                                                • Selected columns are colored in the Header by blue background in the appropriate cells.
                                                                • -
                                                                • The absence of selected columns is equivalent of "all columns are selected".
                                                                • -
                                                                • When the selected lines are displayed, the Input cells of unselected columns are drawn with alpha ~0.4, whereas the cells of the selected columns have alpha ~0.7.
                                                                • -
                                                                • In the column of frame numbers, the selected lines have alpha ~0.4, when the Markers are detached, and ~0.7, when the Markers are attached.
                                                                • -
                                                                • Splicer section displays not only the number of the selected lines (rows), but the number of selected columns (columns).
                                                                • -
                                                                • When you Copy, only the Input from the selected columns is copied to the Clipboard, and it appears there as a rectangular table with no gaps between columns. This allows the user to change the selected columns and insert some buttons in place of the other buttons.
                                                                • -
                                                                • When the SELECTION object is initialized (i.e. at Taseditor startup or project creation), Selection is reset to "no selection of columns".
                                                                • -
                                                                • If you change the order of columns or hide/disclose them, the Selection is reset to "no selection of columns".
                                                                • -
                                                                • When recording, the Input is filtered to match columns selection. Unselected columns will not change, even if the user records a different button state for the column.
                                                                • -
                                                                • Columns selection is also saved in the project file.
                                                                • -
                                                                • This innovation does not affect the Selection History. Changing the Selection of columns is not saved in the Selection History, because there's no need to navigate through column selections history.
                                                                • +


                                                                  +

                                                                  Selection improvement

                                                                  +


                                                                  +

                                                                  TAS Editor 1.0 architecture is not designed to support the selection of Piano Roll columns, but in some situations it may be useful in TASing. For example, to clear the Input of the first joypad without clearing the second joypad Input. Or to shift the Input for one buttons without moving the rest buttons.

                                                                  +

                                                                  Besides, it's necessary to improve the process of painting the Selection, so that users will see the Piano Roll line color under the translucent Selection.

                                                                  +


                                                                  +
                                                                    +
                                                                  • Selecting columns should be done like selecting rows – when you left-click on the Header of the corresponding Piano Roll column, the column is selected, and all other columns are deselected. If you hold down Ctrl before clicking the button, Selection of the rest columns will not disappear. If you hold down Shift, you will select the range of columns from the previous click place. If you hold down Alt, the columns selection will be set by pattern. And of course after clicking you can hold the left mouse button and stretch the selection horizontally.
                                                                  • +
                                                                  • Only Input columns can be selected. The Markers depend on the "Bind Markers to Input" setting.
                                                                  • +
                                                                  • Selected columns are colored in the Header by blue background in the appropriate cells.
                                                                  • +
                                                                  • The absence of selected columns is equivalent of "all columns are selected".
                                                                  • +
                                                                  • When the selected lines are displayed, the Input cells of unselected columns are drawn with alpha ~0.4, whereas the cells of the selected columns have alpha ~0.7.
                                                                  • +
                                                                  • In the column of frame numbers, the selected lines have alpha ~0.4, when the Markers are detached, and ~0.7, when the Markers are attached.
                                                                  • +
                                                                  • Splicer section displays not only the number of the selected lines (rows), but the number of selected columns (columns).
                                                                  • +
                                                                  • When you Copy, only the Input from the selected columns is copied to the Clipboard, and it appears there as a rectangular table with no gaps between columns. This allows the user to change the selected columns and insert some buttons in place of the other buttons.
                                                                  • +
                                                                  • When the SELECTION object is initialized (i.e. at Taseditor startup or project creation), Selection is reset to "no selection of columns".
                                                                  • +
                                                                  • If you change the order of columns or hide/disclose them, the Selection is reset to "no selection of columns".
                                                                  • +
                                                                  • When recording, the Input is filtered to match columns selection. Unselected columns will not change, even if the user records a different button state for the column.
                                                                  • +
                                                                  • Columns selection is also saved in the project file.
                                                                  • +
                                                                  • This innovation does not affect the Selection History. Changing the Selection of columns is not saved in the Selection History, because there's no need to navigate through column selections history.
                                                                  -

                                                                  -

                                                                  -

                                                                  Columns tweaking

                                                                  -


                                                                  -

                                                                  In TAS Editor 1.0 the Piano Roll columns have fixed width. The number and order of the columns are also fixed. There's also no columns dedicated to hardware commands (reset, insert disk, etc.), because these commands are rarely used. However, porting Taseditor to another emulator will increase the number of columns (e.g. PSX needs to display columns for 14 buttons), so it's necessary to give the user the ability to customize them.

                                                                  -


                                                                  -
                                                                    -
                                                                  • Since this setting is typically done only once (when you start using the program), it does not have to be done directly in the Piano Roll, it should be configured in a separate window called from the "Config" menu.
                                                                  • -
                                                                  • The ability to display any Input columns, including the command columns.
                                                                  • -
                                                                  • Ability to hide any columns. However, each joypad must be represented by at least one button column (but if the user has configured project to 1P mode, the second joypad columns in any case will not be displayed).
                                                                  • -
                                                                  • The ability to change the order of the columns.
                                                                  • -
                                                                  • When you Copy to the Clipboard, only the abstract values like true/false are copied. So if after copying you reorder the columns and insert the Input from the Clipboard to the same place, the real movie Input may change (because button columns are swapped).
                                                                  • -
                                                                  • The ability to change the width of columns. For platforms with many buttons (like PC) it's useful to shrink the width of columns down to a few pixels, so that a lot of columns can fit the screen.
                                                                  • -
                                                                  • The possibility to restore the default settings (those recommended by the author) by one click.
                                                                  • -
                                                                  • All settings are saved in config.
                                                                  • -
                                                                  • Все настройки сохраняются при выходе.
                                                                  • +


                                                                    +

                                                                    Columns tweaking

                                                                    +


                                                                    +

                                                                    In TAS Editor 1.0 the Piano Roll columns have fixed width. The number and order of the columns are also fixed. There's also no columns dedicated to hardware commands (reset, insert disk, etc.), because these commands are rarely used. However, porting Taseditor to another emulator will increase the number of columns (e.g. PSX needs to display columns for 14 buttons), so it's necessary to give the user the ability to customize them.

                                                                    +


                                                                    +
                                                                      +
                                                                    • Since this setting is typically done only once (when you start using the program), it does not have to be done directly in the Piano Roll, it should be configured in a separate window called from the "Config" menu.
                                                                    • +
                                                                    • The ability to display any Input columns, including the command columns.
                                                                    • +
                                                                    • Ability to hide any columns. However, each joypad must be represented by at least one button column (but if the user has configured project to 1P mode, the second joypad columns in any case will not be displayed).
                                                                    • +
                                                                    • The ability to change the order of the columns.
                                                                    • +
                                                                    • When you Copy to the Clipboard, only the abstract values like true/false are copied. So if after copying you reorder the columns and insert the Input from the Clipboard to the same place, the real movie Input may change (because button columns are swapped).
                                                                    • +
                                                                    • The ability to change the width of columns. For platforms with many buttons (like PC) it's useful to shrink the width of columns down to a few pixels, so that a lot of columns can fit the screen.
                                                                    • +
                                                                    • The possibility to restore the default settings (those recommended by the author) by one click.
                                                                    • +
                                                                    • All settings are saved in config.
                                                                    • +
                                                                    • Все настройки сохраняются при выходе.
                                                                    -

                                                                    -

                                                                    -

                                                                    Rerecords heatmap

                                                                    -


                                                                    -

                                                                    Stores and displays the statistics about "changes done after watching" (rerecords). It may be useful to identify the difficult places in the movie.

                                                                    -


                                                                    -
                                                                      -
                                                                    • Stores an array of int, one entry for each movie frame (including the frames beyond the current Input). The value corresponds to the number of Greenzone truncations at the frame.
                                                                    • -
                                                                    • Saves and loads the data from the project file.
                                                                    • -
                                                                    • As a canvas for displaying the Heatmap we can use the Minimap canvas. There's no point to constantly see the Heatmap during TASing, so you can just occasionally (e.g. at the end of every day) toggle the Minimap to the Heatmap display mode and evaluate the work.
                                                                    • -
                                                                    • Since this feature is not as much operational as aesthetic, we'll need to think over the Heatmap drawing algorithm, so that it is not only informative but also beautiful.
                                                                    • +


                                                                      +

                                                                      Rerecords heatmap

                                                                      +


                                                                      +

                                                                      Stores and displays the statistics about "changes done after watching" (rerecords). It may be useful to identify the difficult places in the movie.

                                                                      +


                                                                      +
                                                                        +
                                                                      • Stores an array of int, one entry for each movie frame (including the frames beyond the current Input). The value corresponds to the number of Greenzone truncations at the frame.
                                                                      • +
                                                                      • Saves and loads the data from the project file.
                                                                      • +
                                                                      • As a canvas for displaying the Heatmap we can use the Minimap canvas. There's no point to constantly see the Heatmap during TASing, so you can just occasionally (e.g. at the end of every day) toggle the Minimap to the Heatmap display mode and evaluate the work.
                                                                      • +
                                                                      • Since this feature is not as much operational as aesthetic, we'll need to think over the Heatmap drawing algorithm, so that it is not only informative but also beautiful.
                                                                      -

                                                                      -

                                                                      -

                                                                      Other stuff

                                                                      -


                                                                      -
                                                                        -
                                                                      • Separate History Log for the Bookmark Set operations (Alt + Z and Alt + Y), so the user will be able to undo the Input/Markers changes without undoing Bookmarks and vice versa.
                                                                      • -
                                                                      • Work with movies starting from savestate.
                                                                      • -
                                                                      • Work with multiple emulated games simultaneously (for Multi-TAS projects).
                                                                      • -
                                                                      • Lua API improvements.
                                                                      • -
                                                                      • Support for multi-touch controls.
                                                                      • -
                                                                      • Think out the concept of the background greenzoning (how exactly it corresponds to TASing specifics).
                                                                      • +


                                                                        +

                                                                        Other stuff

                                                                        +


                                                                        +
                                                                          +
                                                                        • Separate History Log for the Bookmark Set operations (Alt + Z and Alt + Y), so the user will be able to undo the Input/Markers changes without undoing Bookmarks and vice versa.
                                                                        • +
                                                                        • Work with movies starting from savestate.
                                                                        • +
                                                                        • Work with multiple emulated games simultaneously (for Multi-TAS projects).
                                                                        • +
                                                                        • Lua API improvements.
                                                                        • +
                                                                        • Support for multi-touch controls.
                                                                        • +
                                                                        • Think out the concept of the background greenzoning (how exactly it corresponds to TASing specifics).
                                                                        -

                                                                        -

                                                                        -

                                                                        Supporting platforms other than NES

                                                                        -


                                                                        -

                                                                        If Taseditor gains popularity among TASers, its availability needs to be expanded to all emulated platforms.

                                                                        -


                                                                        -
                                                                          -
                                                                        • Think about the ways to display and change an analog Input using the Piano Roll. The Virtual Joypad partially solves this problem, but the user should also be able to quickly and easily create an analog Input with the mouse. For example, set the "stick tilt" value for one frame and then stretch it to many frames. Also, remember the value of the newly cleared cell and offer it when drawing by mouse. The cells should be able to display not only a single character, but a fixed-point number from -1.0 to +1.0. By double-clicking on a cell you can type the exact value of this number with the keyboard. While holding Ctrl, you can stretch the value of the cell by holding the left button and moving the mouse left/right or up/down. A single column can correlate to only single coordinate axis (thus the analog stick requires two columns in Piano Roll).
                                                                        • -
                                                                        • The Virtual Joypad should provide the ability to draw an envelope for a frame range. It is also necessary to remake the format of patterns file, so that they can represent the sequence of "voltage levels", including relative values (for example, increase in a parabola, where the initial and final values are taken from the initial and final frame of the selected range).
                                                                        • -
                                                                        • Transition to a 64-bit platform is highly desirable, because the Greenzone size is going to increase dramatically when storing savestates for more advanced consoles. 2GB of RAM will not be enough for Taseditor 2.0.
                                                                        • +


                                                                          +

                                                                          Supporting platforms other than NES

                                                                          +


                                                                          +

                                                                          If Taseditor gains popularity among TASers, its availability needs to be expanded to all emulated platforms.

                                                                          +


                                                                          +
                                                                            +
                                                                          • Think about the ways to display and change an analog Input using the Piano Roll. The Virtual Joypad partially solves this problem, but the user should also be able to quickly and easily create an analog Input with the mouse. For example, set the "stick tilt" value for one frame and then stretch it to many frames. Also, remember the value of the newly cleared cell and offer it when drawing by mouse. The cells should be able to display not only a single character, but a fixed-point number from -1.0 to +1.0. By double-clicking on a cell you can type the exact value of this number with the keyboard. While holding Ctrl, you can stretch the value of the cell by holding the left button and moving the mouse left/right or up/down. A single column can correlate to only single coordinate axis (thus the analog stick requires two columns in Piano Roll).
                                                                          • +
                                                                          • The Virtual Joypad should provide the ability to draw an envelope for a frame range. It is also necessary to remake the format of patterns file, so that they can represent the sequence of "voltage levels", including relative values (for example, increase in a parabola, where the initial and final values are taken from the initial and final frame of the selected range).
                                                                          • +
                                                                          • Transition to a 64-bit platform is highly desirable, because the Greenzone size is going to increase dramatically when storing savestates for more advanced consoles. 2GB of RAM will not be enough for Taseditor 2.0.
                                                                          -


                                                                          -


                                                                          -


                                                                          -


                                                                          -


                                                                          +


                                                                          +


                                                                          +


                                                                          +


                                                                          +


                                                                          -

                                                                          Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

                                                                          -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/Implementation.html b/web/help/taseditor/Implementation.html index 667e9c8f..20983308 100644 --- a/web/help/taseditor/Implementation.html +++ b/web/help/taseditor/Implementation.html @@ -1,420 +1,611 @@ - - + + + + + - Implementation - - - - - - - - - - + + + + + + + + Implementation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Implementation

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - -

      -

      Implementation

      -


      -


      -

      At first the TAS Editor was based on the codebase of experimental tool named TASEdit, using FCEUX 2.1.5 as a kick-start.

      -

      The premise of TASEdit was to build an input editor (like TAS Movie Editor) into emulator, so that the delay between editing and checking results would greatly shrink. Since there was no research done on typical behaviors in TASing process, the concept was vague and the code wasn't scalable. Thus, soon after formulating the new vision of the editing tool the code of TAS Editor was fully rewritten to make adding new features easier.

      -

      The premise of TAS Editor is to create a tool that is more handy than traditional rerecording tools, not just for Input editing/splicing, but also for Input creation and, most importantly, polishing (optimizing).

      -

      The following architecture of TAS Editor was designed according to author's notion of a methodical TASing and of features needed for such TASing.

      -


      -
      -


      -

      TAS Editor modules (classes)

      -


      -

      taseditor.cpp

      -

      Main – Main gate between emulator and Taseditor

      -

      [single instance]

      -
        -
      • the point of launching TAS Editor from emulator
      • -
      • the point of quitting from TAS Editor
      • -
      • regularly (at the end of every frame) updates all modules that need regular update
      • -
      • implements operations of the "File" menu: creating New project, opening a file, saving, compact saving, import, export
      • -
      • handles some FCEUX hotkeys
      • -
      -


      -

      taseditor_window.cpp

      -

      Window – User Interface

      -

      [single instance]

      -
        -
      • implements all operations with TAS Editor window: creating, redrawing, resizing, moving, tooltips, clicks
      • -
      • subclasses all buttons and checkboxes in TAS Editor window GUI in order to disable Spacebar key and process Middle clicks
      • -
      • processes OS messages and sends signals from user to TAS Editor modules (also implements some minor commands on-site, like Greenzone capacity dialog and such)
      • -
      • switches off/on emulator's keyboard input when the window loses/gains focus
      • -
      • on demand: updates the window caption; updates mouse cursor icon
      • -
      • updates all checkboxes and menu items when some settings change
      • -
      • stores info about 10 last projects (File->Recent) and updates it when saving/loading files
      • -
      • stores resources: window caption, help filename, size and other properties of all GUI items
      • -
      -


      -

      bookmarks.cpp

      -

      Bookmarks – Manager of Bookmarks

      -

      [single instance]

      -
        -
      • stores 10 Bookmarks
      • -
      • implements all operations with Bookmarks: initialization, setting Bookmarks, jumping to Bookmarks, deploying Branches
      • -
      • saves and loads the data from a project file. On error: resets all Bookmarks and Branches
      • -
      • implements the working of Bookmarks List: creating, redrawing, mouseover, clicks
      • -
      • regularly updates flashings in Bookmarks List
      • -
      • on demand: updates colors of rows in Bookmarks List, reflecting conditions of respective Piano Roll rows
      • -
      • stores resources: save id, ids of commands, labels for panel, gradients for flashings, id of default slot
      • -
      -


      -

      branches.cpp

      -

      Branches – Manager of Branches

      -

      [single instance]

      -
        -
      • stores info about Branches (relations of Bookmarks) and the id of current Branch
      • -
      • also stores the time of the last modification (see fireball) and the time of project beginning (see cloudlet)
      • -
      • also caches data used in calculations (cached_first_difference, cached_timelines)
      • -
      • saves and loads the data from a project file. On error: sends warning to caller
      • -
      • implements the working of Branches Tree: creating, recalculating relations, animating, redrawing, mouseover, clicks
      • -
      • on demand: reacts on Bookmarks/current Movie changes and recalculates the Branches Tree
      • -
      • regularly updates animations in Branches Tree and calculates Playback cursor position on the Tree
      • -
      • stores resources: coordinates for building Branches Tree, animation timings
      • -
      -


      -

      bookmark.cpp

      -

      Bookmark – Single Bookmark data

      -
        -
      • stores all info of one specific Bookmark: movie snapshot, a savestate of 1 frame, a screenshot of the frame, a state of flashing for this Bookmark's row
      • -
      • saves and loads the data from a project file. On error: sends warning to caller
      • -
      • implements procedure of "Bookmark set": creating movie snapshot, setting key frame on current Playback position, copying savestate from Greenzone, making and compressing screenshot, launching flashing animation
      • -
      • launches respective flashings for "Bookmark jump" and "Branch deploy"
      • -
      -


      -

      snapshot.cpp

      -

      Snapshot – Snapshot of all edited data

      -
        -
      • stores the data of specific snapshot of the movie: InputLog, LagLog, Markers at the moment of creating the snapshot, keyframe, start and end frame of operation, type of operation and description of the snapshot (including the time of creation)
      • -
      • also stores info about sequential recording/drawing of input
      • -
      • streamlines snapshot creation: copying Input from movie data, copying LagLog from Greenzone, copying Markers from Markers Manager, setting time of creation
      • -
      • streamlines restoring Markers data from snapshot
      • -
      • saves and loads the data from a project file. On error: sends warning to caller
      • -
      -


      -

      inputlog.cpp

      -

      InputLog – Log of Input

      -
        -
      • stores the data about Input state: size, type of Input, Input Log data (commands and joysticks)
      • -
      • optionally can store map of Hot Changes
      • -
      • implements InputLog creation: copying Input, copying Hot Changes
      • -
      • implements full/partial restoring of data from InputLog: Input, Hot Changes
      • -
      • implements compression and decompression of stored data
      • -
      • saves and loads the data from a project file. On error: sends warning to caller
      • -
      • implements searching of first mismatch comparing two InputLogs or comparing this InputLog to a movie
      • -
      • provides interface for reading specific data: reading Input of any given frame, reading value at any point of Hot Changes map
      • -
      • implements all operations with Hot Changes maps: copying (full/partial), updating/fading, setting new hot places by comparing two InputLogs
      • -
      -


      -

      laglog.cpp

      -

      LagLog – Log of Lag occurrence

      -
        -
      • stores the frame-by-frame log of lag occurrence
      • -
      • implements compression and decompression of stored data
      • -
      • saves and loads the data from a project file. On error: sends warning to caller
      • -
      • provides interface for reading and writing log data
      • -
      -


      -

      markers.cpp

      -

      Markers – Snapshot of Markers state

      -
        -
      • stores the data about Markers state: array of distributing Markers among movie frames, and array of Notes
      • -
      • implements compression and decompression of stored data
      • -
      • saves and loads the data from a project file. On error: sends warning to caller
      • -
      • stores resources: max length of a Note
      • -
      -


      -

      popup_display.cpp

      -

      Popup display – Manager of popup windows

      -

      [single instance]

      -
        -
      • implements all operations with popup windows: initialization, redrawing, centering, screenshot decompression and conversion
      • -
      • regularly inspects changes of Bookmarks Manager and shows/updates/hides popup windows
      • -
      • on demand: updates contents of popup windows
      • -
      • stores resources: coordinates and appearance of popup windows, timings of fade in/out
      • -
      -


      -

      history.cpp

      -

      History – History of movie modifications

      -

      [single instance]

      -
        -
      • stores array of History items (snapshots, backup_bookmarks, backup_current_branch) and pointer to current snapshot
      • -
      • saves and loads the data from a project file. On error: clears the array and starts new history by making snapshot of current movie data
      • -
      • on demand: checks the difference between the last snapshot and current movie, and makes a decision to create new point of rollback. In special cases it can create a point of rollback without checking the difference, assuming that caller already checked it
      • -
      • implements all restoring operations: undo, redo, revert to any snapshot from the array
      • -
      • also stores the state of "undo pointer"
      • -
      • regularly updates the state of "undo pointer"
      • -
      • regularly (when emulator is paused) searches for uncompressed items in the History Log and compresses first found item
      • -
      • implements the working of History List: creating, redrawing, clicks, auto-scrolling
      • -
      • stores resources: save id, ids and names of all possible types of modification, timings of "undo pointer"
      • -
      -


      -

      piano_roll.cpp

      -

      Piano Roll – Piano Roll interface

      -

      [single instance]

      -
        -
      • implements the working of Piano Roll List: creating, redrawing, scrolling, mouseover, clicks, drag
      • -
      • regularly updates the size of the List according to current movie input
      • -
      • on demand: scrolls visible area of the List to any given item: to Playback Cursor, to Selection Cursor, to "undo pointer", to a Marker
      • -
      • saves and loads current position of vertical scrolling from a project file. On error: scrolls the List to the beginning
      • -
      • implements the working of Piano Roll List Header: creating, redrawing, animating, mouseover, clicks
      • -
      • regularly updates lights in the Header according to button presses data from Recorder and Alt key state
      • -
      • on demand: launches flashes in the Header
      • -
      • implements the working of mouse wheel: List scrolling, Playback cursor movement, Selection cursor movement, scrolling across gaps
      • -
      • implements context menu on Right-click
      • -
      • stores resources: save id, ids of columns, widths of columns, tables of colors, gradient of Hot Changes, gradient of Header flashings, timings of flashes, all fonts used in TAS Editor, images
      • -
      -


      -

      selection.cpp

      -

      Selection – Manager of selections

      -

      [single instance]

      -
        -
      • contains definition of the type "Set of selected frames"
      • -
      • stores array of Sets of selected frames (History of selections)
      • -
      • saves and loads the data from a project file. On error: clears the array and starts new history by making empty selection
      • -
      • constantly tracks changes in selected rows of Piano Roll List, and makes a decision to create new point of selection rollback
      • -
      • implements all selection restoring operations: undo, redo
      • -
      • on demand: changes current selection: remove selection, jump to a frame with Selection cursor, select region, select all, select between Markers, reselect clipboard
      • -
      • regularly ensures that selection doesn't go beyond curent Piano Roll limits, detects if selection moved to another Marker and updates Note in the lower text field
      • -
      • implements the working of lower buttons << and >> (jumping on Markers)
      • -
      • also here's the code of lower text field (for editing Marker Notes)
      • -
      • stores resource: save id, lower text field prefix
      • -
      -


      -

      editor.cpp

      -

      Editor – Tool for editing

      -

      [single instance]

      -
        -
      • implements operations of changing Input: toggle input in region, set input by pattern, toggle selected region, apply pattern to input selection
      • -
      • implements operations of changing Markers: toggle Markers in selection, apply patern to Markers in selection, mark/unmark all selected frames
      • -
      • stores Autofire Patterns data and their loading/generating code
      • -
      • stores resources: patterns filename, id of buttonpresses in patterns
      • -
      -


      -

      splicer.cpp

      -

      Splicer – Tool for montage

      -

      [single instance]

      -
        -
      • implements operations of mass-changing input: copy/paste, cloning, clearing region, insertion and deletion of frames, truncating
      • -
      • stores data about the selection used in last "Copy to Clipboard" operation
      • -
      • regularly checks the state of current selection and displays info on GUI, also displays info about input in Clipboard
      • -
      • when launching TAS Editor, it checks Clipboard contents
      • -
      • stores resources: mnemonics of buttons, texts for selection/clipboard info on GUI
      • -
      -


      -

      taseditor_config.cpp

      -

      Config – Current settings

      -

      [single instance]

      -
        -
      • stores current state of all TAS Editor settings
      • -
      • all TAS Editor modules can get or set any data within Config
      • -
      • when launching FCEUX, the emulator writes data from fceux.cfg file to the Config, when exiting it reads the data back to fceux.cfg
      • -
      • stores resources: default values of all settings, min/max values of settings
      • -
      -


      -

      playback.cpp

      -

      Playback – Player of emulation states

      -

      [single instance]

      -
        -
      • implements the working of movie player: show any frame (jump), run/cancel seekng. pause, rewinding
      • -
      • regularly tracks and controls emulation process, prompts redrawing of Piano Roll List rows, finishes seeking when reaching target frame, animates target frame, makes Piano Roll follow Playback cursor, detects if Playback cursor moved to another Marker and updates Note in the upper text field
      • -
      • implements the working of upper buttons << and >> (jumping on Markers)
      • -
      • implements the working of buttons < and > (frame-by-frame movement)
      • -
      • implements the working of button || (pause) and middle mouse button, also reacts on external changes of emulation pause
      • -
      • implements the working of progressbar: init, reset, set value, click (cancel seeking)
      • -
      • also here's the code of upper text field (for editing Marker Notes)
      • -
      • stores resources: upper text field prefix, timings of target frame animation, response times of GUI buttons, progressbar scale
      • -
      -


      -

      greenzone.cpp

      -

      Greenzone – Access zone

      -

      [single instance]

      -
        -
      • stores array of savestates, used for faster movie navigation by Playback cursor
      • -
      • also stores LagLog of current movie Input
      • -
      • saves and loads the data from a project file. On error: truncates Greenzone to last successfully read savestate
      • -
      • regularly checks if there's a savestate of current emulation state, if there's no such savestate in array then creates one and updates lag info for previous frame
      • -
      • implements the working of "Auto-adjust Input according to lag" feature
      • -
      • regularly runs gradual cleaning of the savestates array (for memory saving), deleting oldest savestates
      • -
      • on demand: (when movie input was changed) truncates the size of Greenzone, deleting savestates that became irrelevant because of new input. After truncating it may also move Playback cursor (which must always reside within Greenzone) and may launch Playback seeking
      • -
      • stores resources: save id, properties of gradual cleaning, timing of cleaning
      • -
      -


      -

      recorder.cpp

      -

      Recorder – Tool for input recording

      -

      [single instance]

      -
        -
      • at the moment of recording movie input (at the very end of a frame) by emulator's call the Recorder intercepts input data and applies its filters (multitracking/etc), then reflects input changes into History and Greenzone
      • -
      • regularly tracks virtual joypad buttonpresses and provides data for Piano Roll List Header lights. Also reacts on external changes of Recording status, and updates GUI (Recorder panel and Bookmarks/Branches caption)
      • -
      • implements input editing in Read-only mode (ColumnSet by pressing buttons on virtual joypad)
      • -
      • stores resources: ids and names of multitracking modes, suffixes for TAS Editor window caption
      • -
      -


      -

      markers_manager.cpp

      -

      Markers_manager – Manager of Markers

      -

      [single instance]

      -
        -
      • stores one snapshot of Markers, representing current state of Markers in the project
      • -
      • saves and loads the data from a project file. On error: clears the data
      • -
      • regularly ensures that the size of current Markers array is not less than the number of frames in current input
      • -
      • implements all operations with Markers: setting Marker to a frame, removing Marker, inserting/deleting frames between Markers, truncating Markers array, changing Notes, finding frame for any given Marker, access to the data of Snapshot of Markers state
      • -
      • implements full/partial copying of data between two Snapshots of Markers state, and searching for first difference between two Snapshots of Markers state
      • -
      • also here's the code of searching for "similar" Notes
      • -
      • also here's the code of editing Marker Notes
      • -
      • also here's the code of Find Note dialog
      • -
      • stores resources: save id, properties of searching for similar Notes
      • -
      -


      -

      taseditor_lua.cpp

      -

      Lua – Manager of Lua features

      -

      [single instance]

      -
        -
      • implements logic of all functions of "taseditor" Lua library
      • -
      • stores the list of pending input changes
      • -
      • on demand: (from FCEUX Lua engine) updates "Run function" button
      • -
      • stores resources: ids of joypads for input changes, max length of a name for applychanges(), default caption for the "Run function" button
      • -
      -


      -

      taseditor_project.cpp

      -

      Project – Manager of working project

      -

      [single instance]

      -
        -
      • stores the info about current project filename and about having unsaved changes
      • -
      • implements saving and loading project files from filesystem
      • -
      • implements autosave function
      • -
      • stores resources: autosave period scale, default filename, fm3 format offsets
      • -
      -


      -
      -


      -

      Emulator modifications

      -


      -


      -

      Taseditor needs the following modifications to be applied to an emulator code.

      -


      -

      Main/Window:

      -
        -
      • call Taseditor's update() function after every emulated frame and when emulation is paused, no less than 20 times per second (necessary for smooth animations and controls in TAS Editor window)
      • -
      • dispatch OS messages to Taseditor window, including accelerator table commands
      • -
      • if emulator doesn't make use of mouse wheel, it should resend WM_MOUSEWHEEL to Taseditor, same with middle mouse clicks on emulator's own window
      • -
      • on exit: emulator should ask Taseditor, so it can check unsaved changes in current project and allow user to save before quitting. If the askSave() function returns false, the exit should be cancelled (means that user chose "Cancel")
      • -
      -


      -

      Movie:

      -
        -
      • there should be an interface for full control over the current movie data (creating/reading/writing/any modification). The movie should be the last layer between user's input and emulated game, which means that the game should not take input from virtual pads, only from movie data. An alternative (FCEUX example) would be to always sync changes into virtual pads every time the movie data changes. Either way, Taseditor interacts with the game by reading and modifying movie data and doesn't poll virtual pads. The Piano Roll displays current movie data and edits Input of current movie data only
      • -
      • in Recording mode: at the very beginning of a frame (right after the Input for the frame is written into current movie data) emulator should call Taseditor's Recorder function (and Recorder may change the movie data)
      • -
      -


      -

      Input:

      -
        -
      • provide an interface for knowing which buttons are currently held (it's necessary for the Piano Roll Header)
      • -
      • hardware commands (Reset/Power/etc) should not be executed immediately after user invokes them, they should work as well as buttons input from virtual pads, meaning that when Taseditor is engaged it may either allow or prohibit the commands. In fact, when Taseditor is engaged and is not Recording, user should not be able to even invoke hardware commands
      • -
      -


      -

      Output:

      -
        -
      • provide read access to current state of lag indicator (needed at the end of every frame)
      • -
      • have public function for storing current screenshot in RAM (also screenshot with Lua HUD)
      • -
      -


      -

      SaveStates:

      -
        -
      • have public function for making a savestate in RAM and function for loading the state from RAM array
      • -
      • savestates must restore the game state precisely
      • -
      • saving and loading should not take too much time, because the Greenzone automatically creates a new savestate for every frame, which should be transparent for user
      • -
      • savestates should be stored in compressed form, so that they don't take too much space, because for a comfortable work in Taseditor the Greenzone should have at least 1000 savestates for nearby frames
      • -
      • Greenzone savestates should not store current movie data (that would be a waste of space)
      • -
      -


      -

      Config:

      -
        -
      • on emulator start: emulator should load taseditor_config data from the common settings file. If the file is not found, no changes should be made to taseditor_config (it will have its default settings)
      • -
      • on emulator exit: save taseditor_config data to the common settings file
      • -
      -


      -

      Lua engine:

      -
        -
      • add support for taseditor library. The core of each function is implemented by Taseditor, but emulator should take parameters from Lua stack and send them to respective function of Taseditor's Lua gate, then receive returned data and push it into Lua stack
      • -
      • add support for Manual function and Auto function
      • -
      • notify Taseditor about changing the Manual function status (registered/re-registered/empty) so that it can change the appearance of the "Run function" button
      • -
      -


      -

      Replay:

      -
        -
      • emulator should be able to replay Taseditor project files as usual movie files, ignoring the additional data at the end of the file
      • -
      • since Taseditor project file can be huge, emulator shouldn't load it into memory when opening
      • -
      • emulator should be able to distinguish between a normal movie and a Taseditor project file. If it's a project file: when user tries to rerecord, emulator should refuse and suggest launching TAS Editor instead. If user agrees, emulator should send Taseditor the reference to the project file
      • -
      -


      -

      Other:

      -
        -
      • emulator must be stable and deterministic. Desyncs will totally break Playback cursor navigation and make TASing unfeasible
      • -
      • it's recommended to implement all the points mentioned in Mistake-proofing that are related to emulator modification. In particular, Taseditor should be able to change certain settings, and user shouldn't be able to change them while Taseditor is engaged
      • -
      • good emulation speed is necessary for adequate Turbo seeking feature. Also there should be an option to mute sound when turbo is on.
      • -
      -


      -


      -


      -


      -


      -

      -

      Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

      -
      - - - - + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Implementation

      + +
      + +

      +

      Implementation

      +


      +


      +

      At first the TAS Editor was based on the codebase of experimental tool named TASEdit, using FCEUX 2.1.5 as a kick-start.

      +

      The premise of TASEdit was to build an input editor (like TAS Movie Editor) into emulator, so that the delay between editing and checking results would greatly shrink. Since there was no research done on typical behaviors in TASing process, the concept was vague and the code wasn't scalable. Thus, soon after formulating the new vision of the editing tool the code of TAS Editor was fully rewritten to make adding new features easier.

      +

      The premise of TAS Editor is to create a tool that is more handy than traditional rerecording tools, not just for Input editing/splicing, but also for Input creation and, most importantly, polishing (optimizing).

      +

      The following architecture of TAS Editor was designed according to author's notion of a methodical TASing and of features needed for such TASing.

      +


      +
      +


      +

      TAS Editor modules (classes)

      +


      +

      taseditor.cpp

      +

      Main – Main gate between emulator and Taseditor

      +

      [single instance]

      +
        +
      • the point of launching TAS Editor from emulator
      • +
      • the point of quitting from TAS Editor
      • +
      • regularly (at the end of every frame) updates all modules that need regular update
      • +
      • implements operations of the "File" menu: creating New project, opening a file, saving, compact saving, import, export
      • +
      • handles some FCEUX hotkeys
      • +
      +


      +

      taseditor_window.cpp

      +

      Window – User Interface

      +

      [single instance]

      +
        +
      • implements all operations with TAS Editor window: creating, redrawing, resizing, moving, tooltips, clicks
      • +
      • subclasses all buttons and checkboxes in TAS Editor window GUI in order to disable Spacebar key and process Middle clicks
      • +
      • processes OS messages and sends signals from user to TAS Editor modules (also implements some minor commands on-site, like Greenzone capacity dialog and such)
      • +
      • switches off/on emulator's keyboard input when the window loses/gains focus
      • +
      • on demand: updates the window caption; updates mouse cursor icon
      • +
      • updates all checkboxes and menu items when some settings change
      • +
      • stores info about 10 last projects (File->Recent) and updates it when saving/loading files
      • +
      • stores resources: window caption, help filename, size and other properties of all GUI items
      • +
      +


      +

      bookmarks.cpp

      +

      Bookmarks – Manager of Bookmarks

      +

      [single instance]

      +
        +
      • stores 10 Bookmarks
      • +
      • implements all operations with Bookmarks: initialization, setting Bookmarks, jumping to Bookmarks, deploying Branches
      • +
      • saves and loads the data from a project file. On error: resets all Bookmarks and Branches
      • +
      • implements the working of Bookmarks List: creating, redrawing, mouseover, clicks
      • +
      • regularly updates flashings in Bookmarks List
      • +
      • on demand: updates colors of rows in Bookmarks List, reflecting conditions of respective Piano Roll rows
      • +
      • stores resources: save id, ids of commands, labels for panel, gradients for flashings, id of default slot
      • +
      +


      +

      branches.cpp

      +

      Branches – Manager of Branches

      +

      [single instance]

      +
        +
      • stores info about Branches (relations of Bookmarks) and the id of current Branch
      • +
      • also stores the time of the last modification (see fireball) and the time of project beginning (see cloudlet)
      • +
      • also caches data used in calculations (cached_first_difference, cached_timelines)
      • +
      • saves and loads the data from a project file. On error: sends warning to caller
      • +
      • implements the working of Branches Tree: creating, recalculating relations, animating, redrawing, mouseover, clicks
      • +
      • on demand: reacts on Bookmarks/current Movie changes and recalculates the Branches Tree
      • +
      • regularly updates animations in Branches Tree and calculates Playback cursor position on the Tree
      • +
      • stores resources: coordinates for building Branches Tree, animation timings
      • +
      +


      +

      bookmark.cpp

      +

      Bookmark – Single Bookmark data

      +
        +
      • stores all info of one specific Bookmark: movie snapshot, a savestate of 1 frame, a screenshot of the frame, a state of flashing for this Bookmark's row
      • +
      • saves and loads the data from a project file. On error: sends warning to caller
      • +
      • implements procedure of "Bookmark set": creating movie snapshot, setting key frame on current Playback position, copying savestate from Greenzone, making and compressing screenshot, launching flashing animation
      • +
      • launches respective flashings for "Bookmark jump" and "Branch deploy"
      • +
      +


      +

      snapshot.cpp

      +

      Snapshot – Snapshot of all edited data

      +
        +
      • stores the data of specific snapshot of the movie: InputLog, LagLog, Markers at the moment of creating the snapshot, keyframe, start and end frame of operation, type of operation and description of the snapshot (including the time of creation)
      • +
      • also stores info about sequential recording/drawing of input
      • +
      • streamlines snapshot creation: copying Input from movie data, copying LagLog from Greenzone, copying Markers from Markers Manager, setting time of creation
      • +
      • streamlines restoring Markers data from snapshot
      • +
      • saves and loads the data from a project file. On error: sends warning to caller
      • +
      +


      +

      inputlog.cpp

      +

      InputLog – Log of Input

      +
        +
      • stores the data about Input state: size, type of Input, Input Log data (commands and joysticks)
      • +
      • optionally can store map of Hot Changes
      • +
      • implements InputLog creation: copying Input, copying Hot Changes
      • +
      • implements full/partial restoring of data from InputLog: Input, Hot Changes
      • +
      • implements compression and decompression of stored data
      • +
      • saves and loads the data from a project file. On error: sends warning to caller
      • +
      • implements searching of first mismatch comparing two InputLogs or comparing this InputLog to a movie
      • +
      • provides interface for reading specific data: reading Input of any given frame, reading value at any point of Hot Changes map
      • +
      • implements all operations with Hot Changes maps: copying (full/partial), updating/fading, setting new hot places by comparing two InputLogs
      • +
      +


      +

      laglog.cpp

      +

      LagLog – Log of Lag occurrence

      +
        +
      • stores the frame-by-frame log of lag occurrence
      • +
      • implements compression and decompression of stored data
      • +
      • saves and loads the data from a project file. On error: sends warning to caller
      • +
      • provides interface for reading and writing log data
      • +
      +


      +

      markers.cpp

      +

      Markers – Snapshot of Markers state

      +
        +
      • stores the data about Markers state: array of distributing Markers among movie frames, and array of Notes
      • +
      • implements compression and decompression of stored data
      • +
      • saves and loads the data from a project file. On error: sends warning to caller
      • +
      • stores resources: max length of a Note
      • +
      +


      +

      popup_display.cpp

      +

      Popup display – Manager of popup windows

      +

      [single instance]

      +
        +
      • implements all operations with popup windows: initialization, redrawing, centering, screenshot decompression and conversion
      • +
      • regularly inspects changes of Bookmarks Manager and shows/updates/hides popup windows
      • +
      • on demand: updates contents of popup windows
      • +
      • stores resources: coordinates and appearance of popup windows, timings of fade in/out
      • +
      +


      +

      history.cpp

      +

      History – History of movie modifications

      +

      [single instance]

      +
        +
      • stores array of History items (snapshots, backup_bookmarks, backup_current_branch) and pointer to current snapshot
      • +
      • saves and loads the data from a project file. On error: clears the array and starts new history by making snapshot of current movie data
      • +
      • on demand: checks the difference between the last snapshot and current movie, and makes a decision to create new point of rollback. In special cases it can create a point of rollback without checking the difference, assuming that caller already checked it
      • +
      • implements all restoring operations: undo, redo, revert to any snapshot from the array
      • +
      • also stores the state of "undo pointer"
      • +
      • regularly updates the state of "undo pointer"
      • +
      • regularly (when emulator is paused) searches for uncompressed items in the History Log and compresses first found item
      • +
      • implements the working of History List: creating, redrawing, clicks, auto-scrolling
      • +
      • stores resources: save id, ids and names of all possible types of modification, timings of "undo pointer"
      • +
      +


      +

      piano_roll.cpp

      +

      Piano Roll – Piano Roll interface

      +

      [single instance]

      +
        +
      • implements the working of Piano Roll List: creating, redrawing, scrolling, mouseover, clicks, drag
      • +
      • regularly updates the size of the List according to current movie input
      • +
      • on demand: scrolls visible area of the List to any given item: to Playback Cursor, to Selection Cursor, to "undo pointer", to a Marker
      • +
      • saves and loads current position of vertical scrolling from a project file. On error: scrolls the List to the beginning
      • +
      • implements the working of Piano Roll List Header: creating, redrawing, animating, mouseover, clicks
      • +
      • regularly updates lights in the Header according to button presses data from Recorder and Alt key state
      • +
      • on demand: launches flashes in the Header
      • +
      • implements the working of mouse wheel: List scrolling, Playback cursor movement, Selection cursor movement, scrolling across gaps
      • +
      • implements context menu on Right-click
      • +
      • stores resources: save id, ids of columns, widths of columns, tables of colors, gradient of Hot Changes, gradient of Header flashings, timings of flashes, all fonts used in TAS Editor, images
      • +
      +


      +

      selection.cpp

      +

      Selection – Manager of selections

      +

      [single instance]

      +
        +
      • contains definition of the type "Set of selected frames"
      • +
      • stores array of Sets of selected frames (History of selections)
      • +
      • saves and loads the data from a project file. On error: clears the array and starts new history by making empty selection
      • +
      • constantly tracks changes in selected rows of Piano Roll List, and makes a decision to create new point of selection rollback
      • +
      • implements all selection restoring operations: undo, redo
      • +
      • on demand: changes current selection: remove selection, jump to a frame with Selection cursor, select region, select all, select between Markers, reselect clipboard
      • +
      • regularly ensures that selection doesn't go beyond curent Piano Roll limits, detects if selection moved to another Marker and updates Note in the lower text field
      • +
      • implements the working of lower buttons << and >> (jumping on Markers)
      • +
      • also here's the code of lower text field (for editing Marker Notes)
      • +
      • stores resource: save id, lower text field prefix
      • +
      +


      +

      editor.cpp

      +

      Editor – Tool for editing

      +

      [single instance]

      +
        +
      • implements operations of changing Input: toggle input in region, set input by pattern, toggle selected region, apply pattern to input selection
      • +
      • implements operations of changing Markers: toggle Markers in selection, apply patern to Markers in selection, mark/unmark all selected frames
      • +
      • stores Autofire Patterns data and their loading/generating code
      • +
      • stores resources: patterns filename, id of buttonpresses in patterns
      • +
      +


      +

      splicer.cpp

      +

      Splicer – Tool for montage

      +

      [single instance]

      +
        +
      • implements operations of mass-changing input: copy/paste, cloning, clearing region, insertion and deletion of frames, truncating
      • +
      • stores data about the selection used in last "Copy to Clipboard" operation
      • +
      • regularly checks the state of current selection and displays info on GUI, also displays info about input in Clipboard
      • +
      • when launching TAS Editor, it checks Clipboard contents
      • +
      • stores resources: mnemonics of buttons, texts for selection/clipboard info on GUI
      • +
      +


      +

      taseditor_config.cpp

      +

      Config – Current settings

      +

      [single instance]

      +
        +
      • stores current state of all TAS Editor settings
      • +
      • all TAS Editor modules can get or set any data within Config
      • +
      • when launching FCEUX, the emulator writes data from fceux.cfg file to the Config, when exiting it reads the data back to fceux.cfg
      • +
      • stores resources: default values of all settings, min/max values of settings
      • +
      +


      +

      playback.cpp

      +

      Playback – Player of emulation states

      +

      [single instance]

      +
        +
      • implements the working of movie player: show any frame (jump), run/cancel seekng. pause, rewinding
      • +
      • regularly tracks and controls emulation process, prompts redrawing of Piano Roll List rows, finishes seeking when reaching target frame, animates target frame, makes Piano Roll follow Playback cursor, detects if Playback cursor moved to another Marker and updates Note in the upper text field
      • +
      • implements the working of upper buttons << and >> (jumping on Markers)
      • +
      • implements the working of buttons < and > (frame-by-frame movement)
      • +
      • implements the working of button || (pause) and middle mouse button, also reacts on external changes of emulation pause
      • +
      • implements the working of progressbar: init, reset, set value, click (cancel seeking)
      • +
      • also here's the code of upper text field (for editing Marker Notes)
      • +
      • stores resources: upper text field prefix, timings of target frame animation, response times of GUI buttons, progressbar scale
      • +
      +


      +

      greenzone.cpp

      +

      Greenzone – Access zone

      +

      [single instance]

      +
        +
      • stores array of savestates, used for faster movie navigation by Playback cursor
      • +
      • also stores LagLog of current movie Input
      • +
      • saves and loads the data from a project file. On error: truncates Greenzone to last successfully read savestate
      • +
      • regularly checks if there's a savestate of current emulation state, if there's no such savestate in array then creates one and updates lag info for previous frame
      • +
      • implements the working of "Auto-adjust Input according to lag" feature
      • +
      • regularly runs gradual cleaning of the savestates array (for memory saving), deleting oldest savestates
      • +
      • on demand: (when movie input was changed) truncates the size of Greenzone, deleting savestates that became irrelevant because of new input. After truncating it may also move Playback cursor (which must always reside within Greenzone) and may launch Playback seeking
      • +
      • stores resources: save id, properties of gradual cleaning, timing of cleaning
      • +
      +


      +

      recorder.cpp

      +

      Recorder – Tool for input recording

      +

      [single instance]

      +
        +
      • at the moment of recording movie input (at the very end of a frame) by emulator's call the Recorder intercepts input data and applies its filters (multitracking/etc), then reflects input changes into History and Greenzone
      • +
      • regularly tracks virtual joypad buttonpresses and provides data for Piano Roll List Header lights. Also reacts on external changes of Recording status, and updates GUI (Recorder panel and Bookmarks/Branches caption)
      • +
      • implements input editing in Read-only mode (ColumnSet by pressing buttons on virtual joypad)
      • +
      • stores resources: ids and names of multitracking modes, suffixes for TAS Editor window caption
      • +
      +


      +

      markers_manager.cpp

      +

      Markers_manager – Manager of Markers

      +

      [single instance]

      +
        +
      • stores one snapshot of Markers, representing current state of Markers in the project
      • +
      • saves and loads the data from a project file. On error: clears the data
      • +
      • regularly ensures that the size of current Markers array is not less than the number of frames in current input
      • +
      • implements all operations with Markers: setting Marker to a frame, removing Marker, inserting/deleting frames between Markers, truncating Markers array, changing Notes, finding frame for any given Marker, access to the data of Snapshot of Markers state
      • +
      • implements full/partial copying of data between two Snapshots of Markers state, and searching for first difference between two Snapshots of Markers state
      • +
      • also here's the code of searching for "similar" Notes
      • +
      • also here's the code of editing Marker Notes
      • +
      • also here's the code of Find Note dialog 
      • +
      • stores resources: save id, properties of searching for similar Notes
      • +
      +


      +

      taseditor_lua.cpp

      +

      Lua – Manager of Lua features

      +

      [single instance]

      +
        +
      • implements logic of all functions of "taseditor" Lua library
      • +
      • stores the list of pending input changes
      • +
      • on demand: (from FCEUX Lua engine) updates "Run function" button
      • +
      • stores resources: ids of joypads for input changes, max length of a name for applychanges(), default caption for the "Run function" button
      • +
      +


      +

      taseditor_project.cpp

      +

      Project – Manager of working project

      +

      [single instance]

      +
        +
      • stores the info about current project filename and about having unsaved changes
      • +
      • implements saving and loading project files from filesystem
      • +
      • implements autosave function
      • +
      • stores resources: autosave period scale, default filename, fm3 format offsets
      • +
      +


      +
      +


      +

      Emulator modifications

      +


      +


      +

      Taseditor needs the following modifications to be applied to an emulator code.

      +


      +

      Main/Window:

      +
        +
      • call Taseditor's update() function after every emulated frame and when emulation is paused, no less than 20 times per second (necessary for smooth animations and controls in TAS Editor window)
      • +
      • dispatch OS messages to Taseditor window, including accelerator table commands
      • +
      • if emulator doesn't make use of mouse wheel, it should resend WM_MOUSEWHEEL to Taseditor, same with middle mouse clicks on emulator's own window
      • +
      • on exit: emulator should ask Taseditor, so it can check unsaved changes in current project and allow user to save before quitting. If the askSave() function returns false, the exit should be cancelled (means that user chose "Cancel")
      • +
      +


      +

      Movie:

      +
        +
      • there should be an interface for full control over the current movie data (creating/reading/writing/any modification). The movie should be the last layer between user's input and emulated game, which means that the game should not take input from virtual pads, only from movie data. An alternative (FCEUX example) would be to always sync changes into virtual pads every time the movie data changes. Either way, Taseditor interacts with the game by reading and modifying movie data and doesn't poll virtual pads. The Piano Roll displays current movie data and edits Input of current movie data only
      • +
      • in Recording mode: at the very beginning of a frame (right after the Input for the frame is written into current movie data) emulator should call Taseditor's Recorder function (and Recorder may change the movie data)
      • +
      +


      +

      Input:

      +
        +
      • provide an interface for knowing which buttons are currently held (it's necessary for the Piano Roll Header)
      • +
      • hardware commands (Reset/Power/etc) should not be executed immediately after user invokes them, they should work as well as buttons input from virtual pads, meaning that when Taseditor is engaged it may either allow or prohibit the commands. In fact, when Taseditor is engaged and is not Recording, user should not be able to even invoke hardware commands
      • +
      +


      +

      Output:

      +
        +
      • provide read access to current state of lag indicator (needed at the end of every frame)
      • +
      • have public function for storing current screenshot in RAM (also screenshot with Lua HUD)
      • +
      +


      +

      SaveStates:

      +
        +
      • have public function for making a savestate in RAM and function for loading the state from RAM array
      • +
      • savestates must restore the game state precisely
      • +
      • saving and loading should not take too much time, because the Greenzone automatically creates a new savestate for every frame, which should be transparent for user
      • +
      • savestates should be stored in compressed form, so that they don't take too much space, because for a comfortable work in Taseditor the Greenzone should have at least 1000 savestates for nearby frames
      • +
      • Greenzone savestates should not store current movie data (that would be a waste of space)
      • +
      +


      +

      Config:

      +
        +
      • on emulator start: emulator should load taseditor_config data from the common settings file. If the file is not found, no changes should be made to taseditor_config (it will have its default settings)
      • +
      • on emulator exit: save taseditor_config data to the common settings file
      • +
      +


      +

      Lua engine:

      +
        +
      • add support for taseditor library. The core of each function is implemented by Taseditor, but emulator should take parameters from Lua stack and send them to respective function of Taseditor's Lua gate, then receive returned data and push it into Lua stack
      • +
      • add support for Manual function and Auto function
      • +
      • notify Taseditor about changing the Manual function status (registered/re-registered/empty) so that it can change the appearance of the "Run function" button
      • +
      +


      +

      Replay:

      +
        +
      • emulator should be able to replay Taseditor project files as usual movie files, ignoring the additional data at the end of the file
      • +
      • since Taseditor project file can be huge, emulator shouldn't load it into memory when opening
      • +
      • emulator should be able to distinguish between a normal movie and a Taseditor project file. If it's a project file: when user tries to rerecord, emulator should refuse and suggest launching TAS Editor instead. If user agrees, emulator should send Taseditor the reference to the project file
      • +
      +


      +

      Other:

      +
        +
      • emulator must be stable and deterministic. Desyncs will totally break Playback cursor navigation and make TASing unfeasible
      • +
      • it's recommended to implement all the points mentioned in Mistake-proofing that are related to emulator modification. In particular, Taseditor should be able to change certain settings, and user shouldn't be able to change them while Taseditor is engaged
      • +
      • good emulation speed is necessary for adequate Turbo seeking feature. Also there should be an option to mute sound when turbo is on.
      • +
      +


      +


      +


      +


      +


      +

      +

      Created with the Personal Edition of HelpNDoc: Free EPub producer

      + +
      + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/taseditor/Introduction.html b/web/help/taseditor/Introduction.html index 1e748d67..511c6e1c 100644 --- a/web/help/taseditor/Introduction.html +++ b/web/help/taseditor/Introduction.html @@ -1,145 +1,336 @@ - - + + + + + - 1. Introduction - - - - - - - - - - + + + + + + + + 1. Introduction + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      1. Introduction

      - -
      - Beginner's Guide ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      1. Introduction

      + +
      +

      -

      Introduction

      +

      Introduction



      -

      -

      TASing – the process of creating an extraordinary game playthrough. For a true TASer, just simply beating the game is not enough. You must do something unique, something that would justify the use of tools.

      -

      And that requires a non-standard way of thinking. During a regular playing, almost entire flow of our thoughts is determined by the gameplay rules, and those who try to question the rules are quickly fined with a game over and other means. These trivial psychological methods help the game to direct player's fantasy to an intended path, giving him a credible atmosphere of integral world and keeping him within a craftily devised comfort zone.

      -

      So, to create an extraordinary playthrough, TASer needs to both use emulator tools masterfully and be able to mentally abstract from the original game rules, while still obeying them physically (because TASing is not cheating, we won't influence the game other way than by joypad input).

      -

      Early TASing, just as regular speedrunning, was not too far away from the "normal" gaming process. TASer simply launched an emulator, switched on buttons logging and played a game, saving and loading often enough to fix the most obvious mistakes, slowing down the gameplay at the most intense moments, thus compensating for the slow reaction of the human organism.

      -

      The ability to fix mistakes emancipates man's imagination and incites him to experiment. Illusions of the game realm now confine his mind much less than before. But real-world stereotypes still affect his thinking. For instance, if a harmful object usually kills you, it's only natural to assume it always kills. But in truth it may appear to be killing only at even frame numbers, or when the subpixel value is equal to zero. But how would you guess it using only savestates and slowdown?

      -

      You have to stop being a gamer and become a researcher. And there are tools made exactly for this mental transformation.

      -

      A huge breakthrough in the TASing history was the introduction of Frame Advance – a frame-by-frame emulation. Now when you're TASing, the game is constantly being held paused, thus allowing to analyze every in-game aspect separately. Before, even with a strong slowdown the game still appeared as a coherent stream of events. The stream that the player had to perceive as a complex emotional cocktail. And now with frame-by-frame play TASer can mentally isolate any given event of the current frame. This drastically changes the principles of consuming an in-game information. Material world stereotypes don't dictate how to act in the virtual world anymore, and you see the game more objectively, thus finding imperfections and loopholes in its rules.

      -

      Of course the game still keeps trying to impose typical behavior templates, and they are harder to resist when you're newbie rather than experienced TASer. That's the main reason why a skilled TASer can beat someone's speedrun (even his own old TAS) – not because of handling the tools better, but because of "Déformation professionnelle" that helps to notice vulnerabilities in games.

      -

      Many more TASing tools were invented since then, but the very way of interaction between a TASer and a game remained the same. Using rerecords, TASer edits Input in the same succession as the flow of in-game time. This linearity of TASing process builds certain limits in TASer's thinking. When you get used to receiving the game reaction on each button press, you involuntarily associate yourself with a game character. This makes it harder to look at the events from an outsider's viewpoint. And yet a TASer is expected to have the most objective point of view possible. Thus we need further transformation of TASer's way of perception.

      -


      -

      The development of the toolset named "TAS Editor" aims for 2 main goals:

      -
        -
      1. to lower the threshold of joining TASing
      2. -
      3. to raise the objectivity of gameplay analysis
      4. +

        +

        TASing – the process of creating an extraordinary game playthrough. For a true TASer, just simply beating the game is not enough. You must do something unique, something that would justify the use of tools.

        +

        And that requires a non-standard way of thinking. During a regular playing, almost entire flow of our thoughts is determined by the gameplay rules, and those who try to question the rules are quickly fined with a game over and other means. These trivial psychological methods help the game to direct player's fantasy to an intended path, giving him a credible atmosphere of integral world and keeping him within a craftily devised comfort zone.

        +

        So, to create an extraordinary playthrough, TASer needs to both use emulator tools masterfully and be able to mentally abstract from the original game rules, while still obeying them physically (because TASing is not cheating, we won't influence the game other way than by joypad input).

        +

        Early TASing, just as regular speedrunning, was not too far away from the "normal" gaming process. TASer simply launched an emulator, switched on buttons logging and played a game, saving and loading often enough to fix the most obvious mistakes, slowing down the gameplay at the most intense moments, thus compensating for the slow reaction of the human organism.

        +

        The ability to fix mistakes emancipates man's imagination and incites him to experiment. Illusions of the game realm now confine his mind much less than before. But real-world stereotypes still affect his thinking. For instance, if a harmful object usually kills you, it's only natural to assume it always kills. But in truth it may appear to be killing only at even frame numbers, or when the subpixel value is equal to zero. But how would you guess it using only savestates and slowdown?

        +

        You have to stop being a gamer and become a researcher. And there are tools made exactly for this mental transformation.

        +

        A huge breakthrough in the TASing history was the introduction of Frame Advance – a frame-by-frame emulation. Now when you're TASing, the game is constantly being held paused, thus allowing to analyze every in-game aspect separately. Before, even with a strong slowdown the game still appeared as a coherent stream of events. The stream that the player had to perceive as a complex emotional cocktail. And now with frame-by-frame play TASer can mentally isolate any given event of the current frame. This drastically changes the principles of consuming an in-game information. Material world stereotypes don't dictate how to act in the virtual world anymore, and you see the game more objectively, thus finding imperfections and loopholes in its rules.

        +

        Of course the game still keeps trying to impose typical behavior templates, and they are harder to resist when you're newbie rather than experienced TASer. That's the main reason why a skilled TASer can beat someone's speedrun (even his own old TAS) – not because of handling the tools better, but because of "Déformation professionnelle" that helps to notice vulnerabilities in games.

        +

        Many more TASing tools were invented since then, but the very way of interaction between a TASer and a game remained the same. Using rerecords, TASer edits Input in the same succession as the flow of in-game time. This linearity of TASing process builds certain limits in TASer's thinking. When you get used to receiving the game reaction on each button press, you involuntarily associate yourself with a game character. This makes it harder to look at the events from an outsider's viewpoint. And yet a TASer is expected to have the most objective point of view possible. Thus we need further transformation of TASer's way of perception.

        +


        +

        The development of the toolset named "TAS Editor" aims for 2 main goals:

        +
          +
        1. to lower the threshold of joining TASing
        2. +
        3. to raise the objectivity of gameplay analysis
        -


        -

        The first goal is achieved by detailed visualization of all major aspects of TASing.

        -

        The second goal is achieved by switching from linear recording of movie segments to non-linear Input editing. The higher level of abstracting from in-game rules is reached by giving the TASer the following new abilities:

        -
          -
        • changing Input in any arbitrary order (not just in the order the events flow in the game) – thanks to Piano Roll interface
        • -
        • watching game events in an arbitrary order (not just frame by frame) – thanks to Greenzone
        • -
        • emphasizing the Cause-Effect relation between Input and its remote consequences (not just the nearest ones) – thanks to Turbo-seeking
        • -
        • enforcing custom logic of the movie segmentation (not just dividing into TV frames or into in-game levels) – thanks to Markers
        • +


          +

          The first goal is achieved by detailed visualization of all major aspects of TASing.

          +

          The second goal is achieved by switching from linear recording of movie segments to non-linear Input editing. The higher level of abstracting from in-game rules is reached by giving the TASer the following new abilities:

          +
            +
          • changing Input in any arbitrary order (not just in the order the events flow in the game) – thanks to Piano Roll interface
          • +
          • watching game events in an arbitrary order (not just frame by frame) – thanks to Greenzone
          • +
          • emphasizing the Cause-Effect relation between Input and its remote consequences (not just the nearest ones) – thanks to Turbo-seeking
          • +
          • enforcing custom logic of the movie segmentation (not just dividing into TV frames or into in-game levels) – thanks to Markers
          -


          -

          In addition, TAS Editor 1.0 developed some old TASing tools up to a new level:

          -
            -
          • Lag log – evolved from Lag counter
          • -
          • Input log – evolved from Input Display
          • -
          • step-by-step undo – in addition to movie state reloads
          • -
          • inbuilt editor – in place of hex-editors and a Notepad
          • -
          • auto-identification of current logical segment – in addition to current frame number display
          • -
          • Selection counter (ruler) – in addition to frame counter
          • -
          • patterns – in place of Autofire settings
          • -
          • Superimpose – in place of Auto-hold
          • +


            +

            In addition, TAS Editor 1.0 developed some old TASing tools up to a new level:

            +
              +
            • Lag log – evolved from Lag counter
            • +
            • Input log – evolved from Input Display
            • +
            • step-by-step undo – in addition to movie state reloads
            • +
            • inbuilt editor – in place of hex-editors and a Notepad
            • +
            • auto-identification of current logical segment – in addition to current frame number display
            • +
            • Selection counter (ruler) – in addition to frame counter
            • +
            • patterns – in place of Autofire settings
            • +
            • Superimpose – in place of Auto-hold
            -


            -

            When launching Taseditor, get ready to control the game from bird's eye view. The following chapters of this tutorial will explain you almost everything a prolific TASer needs to know. If you already have an experience in traditional TASing, some learning aspects should come easier, but some may appear more difficult to you than to a newcomer. Either way, try to finish the whole Guide, and you will likely learn a thing or two about TASing in general.

            -

            One of the most unconventional features of TASing with Taseditor is the stress on mouse control. Mouse allows high speed of Input editing and unparalleled convenience of Playback navigation. Even though most of Taseditor functions also have keyboard shortcuts, the comfortable work would be impossible without a mouse.

            -

            The gamepad is useful when you need to quickly record an Input without caring about accuracy. But most of his time TASer spends on various manipulations with once created Input. And here the mouse or keyboard becomes much more handy than gamepad. For example, using a key combination you can move any part of Input one frame back or forth. And when you need to adjust the jump height (the duration of holding the A button), it's easier to do it with single click, than to switch Recording on and retype the whole range of frames.

            -

            Nevertheless, it's still possible to work in Taseditor the same way people were TASing before. The program interface supports all essential aspects of the traditional TASing method. If you were to use the TAS Editor window only as an informational panel left in a corner of the desktop, you probably would not even notice any difference from usual flow of TASing. It can be good reason to smoothly move from the old method of TASing to the new one. At first you may only like some accessory features of Taseditor, such as the Lag visualization or the Branches Tree. Then you'll need some Input copy/paste, and Taseditor is better alternative to an external editor. After some time you'll notice that direct Input editing turns out faster than rerecording.

            -

            -

            Advantages of the new method reveal themselves quicker when you're making a TAS controlling 2 and more players simultaneously. In old times people invented plenty of hacks and workarounds to make such kind of TASing easier, e.g. binding several buttons to one key, using "Auto-hold", macros and custom multitracking scripts. Now all of this is irrelevant with Taseditor, because here TASer does not play the role of a gamer that associates himself with the controlled character. Now you are not playing the game, you are meditating over the decomposed continuum of the game, while creating a scenario of events via Input. And thus it's does not matter whether you control 1 character, or 2, or many.

            -


            -

            Taseditor was also designed to reduce the rut. There are always lots of tedious recurring activities in TASing. Surely, the program won't save you from the necessity to test all possible branches of gameplay development, but it automates some actions and increases the efficiency in many little things, allowing TASer to keep patience longer than during raw TASing.

            -


            -

            Interesting facts:

            -
              -
            • During the development of TAS Editor the actual programming took less time than was spent on figuring out the ways to improve the TASing process.
            • -
            • Most of the actions in Taseditor can be done multiple ways.
            • -
            • Any operation can be undone and redone.
            • -
            • You can totally ignore any part of Taseditor's functionality, using only the features you actually like.
            • +


              +

              When launching Taseditor, get ready to control the game from bird's eye view. The following chapters of this tutorial will explain you almost everything a prolific TASer needs to know. If you already have an experience in traditional TASing, some learning aspects should come easier, but some may appear more difficult to you than to a newcomer. Either way, try to finish the whole Guide, and you will likely learn a thing or two about TASing in general.

              +

              One of the most unconventional features of TASing with Taseditor is the stress on mouse control. Mouse allows high speed of Input editing and unparalleled convenience of Playback navigation. Even though most of Taseditor functions also have keyboard shortcuts, the comfortable work would be impossible without a mouse.

              +

              The gamepad is useful when you need to quickly record an Input without caring about accuracy. But most of his time TASer spends on various manipulations with once created Input. And here the mouse or keyboard becomes much more handy than gamepad. For example, using a key combination you can move any part of Input one frame back or forth. And when you need to adjust the jump height (the duration of holding the A button), it's easier to do it with single click, than to switch Recording on and retype the whole range of frames.

              +

              Nevertheless, it's still possible to work in Taseditor the same way people were TASing before. The program interface supports all essential aspects of the traditional TASing method. If you were to use the TAS Editor window only as an informational panel left in a corner of the desktop, you probably would not even notice any difference from usual flow of TASing. It can be good reason to smoothly move from the old method of TASing to the new one. At first you may only like some accessory features of Taseditor, such as the Lag visualization or the Branches Tree. Then you'll need some Input copy/paste, and Taseditor is better alternative to an external editor. After some time you'll notice that direct Input editing turns out faster than rerecording.

              +

              +

              Advantages of the new method reveal themselves quicker when you're making a TAS controlling 2 and more players simultaneously. In old times people invented plenty of hacks and workarounds to make such kind of TASing easier, e.g. binding several buttons to one key, using "Auto-hold", macros and custom multitracking scripts. Now all of this is irrelevant with Taseditor, because here TASer does not play the role of a gamer that associates himself with the controlled character. Now you are not playing the game, you are meditating over the decomposed continuum of the game, while creating a scenario of events via Input. And thus it's does not matter whether you control 1 character, or 2, or many.

              +


              +

              Taseditor was also designed to reduce the rut. There are always lots of tedious recurring activities in TASing. Surely, the program won't save you from the necessity to test all possible branches of gameplay development, but it automates some actions and increases the efficiency in many little things, allowing TASer to keep patience longer than during raw TASing.

              +


              +

              Interesting facts:

              +
                +
              • During the development of TAS Editor the actual programming took less time than was spent on figuring out the ways to improve the TASing process.
              • +
              • Most of the actions in Taseditor can be done multiple ways.
              • +
              • Any operation can be undone and redone.
              • +
              • You can totally ignore any part of Taseditor's functionality, using only the features you actually like.
              -


              -

              Special attention was paid to user interface. When you gain enough experience, you'll be able to do most of things mechanically, staying focused on the in-game situation analysis.

              -

              If you happen to get a nice idea how to reduce the rut some more, feel free to post on TASVideos forums. Many ideas implemented in TAS Editor were first voiced on these forums as "dream tools".

              -


              -

              Besides the new approach to TASing, Taseditor offers simple means for organization of your working process. Because of unsystematic approach to TASing many newcomers waste their time ineffectively, dissipate the effort and get tired quickly, then start to save the energy by reducing the amount of tests. As a result, they end up with a very suboptimal TAS. Then, as the time goes, they acquire a set of methods and habits, become experienced TASers. But every newbie had to learn by his own mistakes. In this Guide we will try to formulate a clear notion on a methodical TASing (both traditional and new), so that newcomers can realize the essence of the process faster.

              -

              Working with Taseditor is pretty similar to an interactive programming using an interpreted language. You just edit the code and instantly see the result of its execution on the screen. TASer can either immediately observe the effect of his interim actions, or he can get carried away by the construction of a code section and watch the result only after the section is finished.

              -

              Programmers have the valuable ability to increase the code readability with comments. It allows to keep more clear picture of the project in mind, and proceed without constant re-inspection of results, because in most cases the result is rather predictable, when the context is known. Also, good code readability allows to quickly refresh all necessary memories when you return to a project delayed long ago. Granted that this project was well documented.

              -

              Taseditor encourages documenting of TAS projects on the fly – you can write comments, assign clear names to structures (patterns and Input sections), test different code versions in separate branches of the repository (see "Branches Tree") and efficiently work in co-authorship. And no, there's no strict conventions to follow. You set your own rules for when and how to shape your project. For example, if you didn't hesitate to describe a trick used in the first level, in next levels you'll be able to quickly duplicate the trick's Input by several key strokes. If you didn't – you'll have to search the trick location manually. In simple TASes you can disregard comments and any long-term plans, but in complicated projects this program functionality should be very appropriate.

              -

              TASVideos.org site supports uploading and publishing Taseditor projects (.fm3 files), so you can publish not just the TAS movie, but your groundwork as well, encouraging the spirit of openness and mutual aid. If you don't want to share, export the data to .fm2 format and upload that.

              -

              FM3 files are played back by FCEUX emulator since version 2.2.0 the same way as FM2 files. Older versions of FCEUX can also play such files if you change the extension to fm2.

              -


              -

              Next chapter: learning the basics of the program usage.

              -


              -


              -


              -


              -


              +


              +

              Special attention was paid to user interface. When you gain enough experience, you'll be able to do most of things mechanically, staying focused on the in-game situation analysis.

              +

              If you happen to get a nice idea how to reduce the rut some more, feel free to post on TASVideos forums. Many ideas implemented in TAS Editor were first voiced on these forums as "dream tools".

              +


              +

              Besides the new approach to TASing, Taseditor offers simple means for organization of your working process. Because of unsystematic approach to TASing many newcomers waste their time ineffectively, dissipate the effort and get tired quickly, then start to save the energy by reducing the amount of tests. As a result, they end up with a very suboptimal TAS. Then, as the time goes, they acquire a set of methods and habits, become experienced TASers. But every newbie had to learn by his own mistakes. In this Guide we will try to formulate a clear notion on a methodical TASing (both traditional and new), so that newcomers can realize the essence of the process faster.

              +

              Working with Taseditor is pretty similar to an interactive programming using an interpreted language. You just edit the code and instantly see the result of its execution on the screen. TASer can either immediately observe the effect of his interim actions, or he can get carried away by the construction of a code section and watch the result only after the section is finished.

              +

              Programmers have the valuable ability to increase the code readability with comments. It allows to keep more clear picture of the project in mind, and proceed without constant re-inspection of results, because in most cases the result is rather predictable, when the context is known. Also, good code readability allows to quickly refresh all necessary memories when you return to a project delayed long ago. Granted that this project was well documented.

              +

              Taseditor encourages documenting of TAS projects on the fly – you can write comments, assign clear names to structures (patterns and Input sections), test different code versions in separate branches of the repository (see "Branches Tree") and efficiently work in co-authorship. And no, there's no strict conventions to follow. You set your own rules for when and how to shape your project. For example, if you didn't hesitate to describe a trick used in the first level, in next levels you'll be able to quickly duplicate the trick's Input by several key strokes. If you didn't – you'll have to search the trick location manually. In simple TASes you can disregard comments and any long-term plans, but in complicated projects this program functionality should be very appropriate.

              +

              TASVideos.org site supports uploading and publishing Taseditor projects (.fm3 files), so you can publish not just the TAS movie, but your groundwork as well, encouraging the spirit of openness and mutual aid. If you don't want to share, export the data to .fm2 format and upload that.

              +

              FM3 files are played back by FCEUX emulator since version 2.2.0 the same way as FM2 files. Older versions of FCEUX can also play such files if you change the extension to fm2.

              +


              +

              Next chapter: learning the basics of the program usage.

              +


              +


              +


              +


              +


              -

              Created with the Personal Edition of HelpNDoc: Easily create iPhone documentation

              -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/LuaAPI.html b/web/help/taseditor/LuaAPI.html index 14b947db..cec435c5 100644 --- a/web/help/taseditor/LuaAPI.html +++ b/web/help/taseditor/LuaAPI.html @@ -1,328 +1,495 @@ - - + + + + + - Lua API - - - - - - - - - - + + + + + + + + Lua API + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Lua API

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Lua API

      + +
      +

      -

      Lua API

      +

      Lua API


      -


      -

      TAS Editor v1.0 comes with the library of 24 functions available for Lua scripts running in FCEUX emulator. With Lua scripts you can automate some aspects of TASing and even create your own tools for movie editing.

      -


      -

      In FCEUX folder there's /luaScripts folder with /taseditor subfolder in it. There you can find examples of scripts using functions of this library.

      -


      -

      If you don't know how to make and run Lua scripts in emulators, read Advanced Features and also refer to FCEUX Help.

      -


      -
      -

      Full list of functions:

      -


      -

      taseditor.registerauto(function func)

      -

      taseditor.registermanual(function func, [string name])

      -


      -

      bool taseditor.engaged()

      -


      -

      bool taseditor.markedframe(int frame)

      -

      int taseditor.getmarker(int frame)

      -

      int taseditor.setmarker(int frame)

      -

      taseditor.removemarker(int frame)

      -

      string taseditor.getnote(int index)

      -

      taseditor.setnote(int index, string newtext)

      -


      -

      int taseditor.getcurrentbranch()

      -


      -

      string taseditor.getrecordermode()

      -

      int taseditor.getsuperimpose()

      -


      -

      int taseditor.getlostplayback()

      -

      int taseditor.getplaybacktarget()

      -

      taseditor.setplayback(int frame)

      -

      taseditor.stopseeking()

      -


      -

      table taseditor.getselection()

      -

      taseditor.setselection(table new_set)

      -


      -

      int taseditor.getinput(int frame, int joypad)

      -

      taseditor.submitinputchange(int frame, int joypad, int input)

      -

      taseditor.submitinsertframes(int frame, int number)

      -

      taseditor.submitdeleteframes(int frame, int number)

      -

      int taseditor.applyinputchanges([string name])

      -

      taseditor.clearinputchanges()

      -


      -
      -

      -

      -

      taseditor.registerauto(function func)

      -


      -

      Registers a callback function ("Auto Function") that runs periodically. The Auto Function can be registered and will be called even when TAS Editor isn't engaged.

      -

      When FCEUX is unpaused, your function will be called at the end of every frame (running 60 times per second on NTSC and 50 times per second on PAL).

      -

      When FCEUX is paused, your function will be called 20 times per second.

      -

      User can switch on/off auto-calling by checking "Auto function" checkbox in TAS Editor GUI.

      -

      Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to taseditor.registerauto() will return the old callback. You may register nil instead of a function to clear a previously-registered callback.

      -

      If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.

      -

      -

      -

      taseditor.registermanual(function func, [string name])

      -


      -

      Registers a callback function ("Manual Function") that can be called manually by TAS Editor user. The function can be registered even when TAS Editor isn't engaged.

      -

      The Manual function doesn't depend on paused or unpaused FCEUX status. It will be called once every time user presses Run function button in TAS Editor GUI.

      -

      You can provide a new name for this button.

      -

      The Manual function cannot be run more often than TAS Editor window updates (60/50 FPS or 20FPS when emulator is paused).

      -

      In FCEUX code Manual function runs right after Auto Function.

      -

      You can use this feature to create new tools for TAS Editor. For example, you can write a script that reverses currently selected input, so user will be able to reverse input by selecting a range and clicking Run function button.

      -

      Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to taseditor.registermanual() will return the old callback. You may call taseditor.registermanual(nil) to clear a previously-registered callback.

      -

      If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.

      -

      -

      -

      bool taseditor.engaged()

      -


      -

      Returns true if TAS Editor is currently engaged, false if otherwise.

      -

      Also when TAS Editor is engaged, movie.mode() returns "taseditor" string.

      -

      -

      -

      bool taseditor.markedframe(int frame)

      -


      -

      Returns true if given frame is marked in TAS Editor, false if not marked.

      -

      If TAS Editor is not engaged, returns false.

      -

      -

      -

      int taseditor.getmarker(int frame)

      -


      -

      Returns index number of the Marker under which given frame is located.

      -

      Returns -1 if TAS Editor is not engaged.

      -

      -

      -

      int taseditor.setmarker(int frame)

      -


      -

      Sets Marker on given frame. Returns index number of the Marker created.

      -

      If that frame is already marked, no changes will be made, and the function will return the index number of existing Marker.

      -

      You can set markers even outside input range.

      -

      If TAS Editor is not engaged, returns -1.

      -

      -

      -

      taseditor.removemarker(int frame)

      -


      -

      Removes marker from given frame. If that frame was not marked, no changes will be made.

      -

      If TAS Editor is not engaged, no changes will be made.

      -

      -

      -

      string taseditor.getnote(int index)

      -


      -

      Returns string representing the Note of given Marker.

      -

      Returns nil if TAS Editor is not engaged.

      -

      If given index is invalid (if Marker with this index number doesn't exist), returns note of the zeroth marker.

      -

      -

      -

      taseditor.setnote(int index, string newtext)

      -


      -

      Sets text of the Note of given Marker.

      -

      If given index is invalid (if Marker with this index number doesn't exist), no changes will be made.

      -

      If TAS Editor is not engaged, no changes will be made.

      -

      -

      -

      int taseditor.getcurrentbranch()

      -


      -

      Returns number from 0 to 9 representing current Branch.

      -

      Returns -1 if there's no Branches or if TAS Editor is not engaged.

      -

      -

      -

      string taseditor.getrecordermode()

      -


      -

      Returns string representing current recorder mode.

      -
        -
      • "All"
      • -
      • "1P"
      • -
      • "2P"
      • -
      • "3P"
      • -
      • "4P"
      • +


        +

        TAS Editor v1.0 comes with the library of 24 functions available for Lua scripts running in FCEUX emulator. With Lua scripts you can automate some aspects of TASing and even create your own tools for movie editing.

        +


        +

        In FCEUX folder there's /luaScripts folder with /taseditor subfolder in it. There you can find examples of scripts using functions of this library.

        +


        +

        If you don't know how to make and run Lua scripts in emulators, read Advanced Features and also refer to FCEUX Help.

        +


        +
        +

        Full list of functions:

        +


        +

        taseditor.registerauto(function func)

        +

        taseditor.registermanual(function func, [string name])

        +


        +

        bool taseditor.engaged()

        +


        +

        bool taseditor.markedframe(int frame)

        +

        int taseditor.getmarker(int frame)

        +

        int taseditor.setmarker(int frame)

        +

        taseditor.removemarker(int frame)

        +

        string taseditor.getnote(int index)

        +

        taseditor.setnote(int index, string newtext)

        +


        +

        int taseditor.getcurrentbranch()

        +


        +

        string taseditor.getrecordermode()

        +

        int taseditor.getsuperimpose()

        +


        +

        int taseditor.getlostplayback()

        +

        int taseditor.getplaybacktarget()

        +

        taseditor.setplayback(int frame)

        +

        taseditor.stopseeking()

        +


        +

        table taseditor.getselection()

        +

        taseditor.setselection(table new_set)

        +


        +

        int taseditor.getinput(int frame, int joypad)

        +

        taseditor.submitinputchange(int frame, int joypad, int input)

        +

        taseditor.submitinsertframes(int frame, int number)

        +

        taseditor.submitdeleteframes(int frame, int number)

        +

        int taseditor.applyinputchanges([string name])

        +

        taseditor.clearinputchanges()

        +


        +
        +


        +

        taseditor.registerauto(function func)

        +


        +

        Registers a callback function ("Auto Function") that runs periodically. The Auto Function can be registered and will be called even when TAS Editor isn't engaged.

        +

        When FCEUX is unpaused, your function will be called at the end of every frame (running 60 times per second on NTSC and 50 times per second on PAL).

        +

        When FCEUX is paused, your function will be called 20 times per second.

        +

        User can switch on/off auto-calling by checking "Auto function" checkbox in TAS Editor GUI.

        +

        Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to taseditor.registerauto() will return the old callback. You may register nil instead of a function to clear a previously-registered callback.

        +

        If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.

        +


        +

        taseditor.registermanual(function func, [string name])

        +


        +

        Registers a callback function ("Manual Function") that can be called manually by TAS Editor user. The function can be registered even when TAS Editor isn't engaged.

        +

        The Manual function doesn't depend on paused or unpaused FCEUX status. It will be called once every time user presses Run function button in TAS Editor GUI.

        +

        You can provide a new name for this button.

        +

        The Manual function cannot be run more often than TAS Editor window updates (60/50 FPS or 20FPS when emulator is paused).

        +

        In FCEUX code Manual function runs right after Auto Function.

        +

        You can use this feature to create new tools for TAS Editor. For example, you can write a script that reverses currently selected input, so user will be able to reverse input by selecting a range and clicking Run function button.

        +

        Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to taseditor.registermanual() will return the old callback. You may call taseditor.registermanual(nil) to clear a previously-registered callback.

        +

        If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.

        +


        +

        bool taseditor.engaged()

        +


        +

        Returns true if TAS Editor is currently engaged, false if otherwise.

        +

        Also when TAS Editor is engaged, movie.mode() returns "taseditor" string.

        +


        +

        bool taseditor.markedframe(int frame)

        +


        +

        Returns true if given frame is marked in TAS Editor, false if not marked.

        +

        If TAS Editor is not engaged, returns false.

        +


        +

        int taseditor.getmarker(int frame)

        +


        +

        Returns index number of the Marker under which given frame is located.

        +

        Returns -1 if TAS Editor is not engaged.

        +


        +

        int taseditor.setmarker(int frame)

        +


        +

        Sets Marker on given frame. Returns index number of the Marker created.

        +

        If that frame is already marked, no changes will be made, and the function will return the index number of existing Marker.

        +

        You can set markers even outside input range.

        +

        If TAS Editor is not engaged, returns -1.

        +


        +

        taseditor.removemarker(int frame)

        +


        +

        Removes marker from given frame. If that frame was not marked, no changes will be made.

        +

        If TAS Editor is not engaged, no changes will be made.

        +


        +

        string taseditor.getnote(int index)

        +


        +

        Returns string representing the Note of given Marker.

        +

        Returns nil if TAS Editor is not engaged.

        +

        If given index is invalid (if Marker with this index number doesn't exist), returns note of the zeroth marker.

        +


        +

        taseditor.setnote(int index, string newtext)

        +


        +

        Sets text of the Note of given Marker.

        +

        If given index is invalid (if Marker with this index number doesn't exist), no changes will be made.

        +

        If TAS Editor is not engaged, no changes will be made.

        +


        +

        int taseditor.getcurrentbranch()

        +


        +

        Returns number from 0 to 9 representing current Branch.

        +

        Returns -1 if there's no Branches or if TAS Editor is not engaged.

        +


        +

        string taseditor.getrecordermode()

        +


        +

        Returns string representing current recorder mode.

        +
          +
        • "All"
        • +
        • "1P"
        • +
        • "2P"
        • +
        • "3P"
        • +
        • "4P"
        -

        Returns nil if TAS Editor is not engaged.

        -

        When you want to check Recorder's read-only state, use emu.readonly().

        -

        -

        -

        int taseditor.getsuperimpose()

        -


        -

        Returns number representing current state of Superimpose checkbox in TAS Editor GUI.

        -

        0 – unchecked

        -

        1 – checked

        -

        2 – indeterminate (you can interpret is as half-checked)

        -

        If TAS Editor is not engaged, returns -1.

        -

        -

        -

        int taseditor.getlostplayback()

        -


        -

        Returns the number of the frame where Playback cursor was before input was changed.

        -

        If Playback didn't lose position during Greenzone invalidation, returns -1.

        -

        If TAS Editor is not engaged, returns -1.

        -

        -

        -

        int taseditor.getplaybacktarget()

        -


        -

        If TAS Editor's Playback is currently seeking, returns number of target frame.

        -

        If Playback is not seeking or if TAS Editor is not engaged, returns -1.

        -

        -

        -

        taseditor.setplayback(int frame)

        -


        -

        Sends Playback cursor (current frame counter) to given frame.

        -

        If given frame wasn't found in TAS Editor Greenzone, starts seeking to the frame.

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        taseditor.stopseeking()

        -


        -

        Stops Playback seeking and pauses emulation.

        -

        If Playback wasn't seeking, this function only pauses emulation.

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        table taseditor.getselection()

        -


        -

        Returns a table (array) containing numbers of currently selected frames. These numbers are sorted in ascending order.

        -

        If no frames are selected at the moment, returns nil.

        -

        If TAS Editor is not engaged, returns nil.

        -

        -

        -

        taseditor.setselection(table new_set)

        -


        -

        Changes current selection to the given set of frames. Frame number in your table don't have to be sorted.

        -

        Call taseditor.setselection(nil) to clear selection.

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        int taseditor.getinput(int frame, int joypad)

        -


        -

        Returns a number representing input of given joypad stored in current movie at given frame.

        -

        If given frame is negative, returns -1.

        -

        If given frame is outside current input range, returns 0, which can be interpreted as a blank frame (no buttons pressed at this frame yet).

        -

        Joypad value must be one of the following:

        -

        0 – to get hardware commands (bit 0 = reset, bit 1 = poweron, bit 2 = FDS insert disk, bit 3 = FDS switch side)

        -

        1 – to get 1P buttons (bit 0 = A, bit 1 = B, bit 2 = Select, bit 3 = Start, bit 4 = Up, bit 5 = Down, bit 6 = Left, bit 7 = Right)

        -

        2 – to get 2P buttons

        -

        3 – to get 3P buttons

        -

        4 – to get 4P buttons

        -

        You should handle returned number (if it's not equal to -1) as a byte, each bit corresponds to one button (e.g. if bit 1 is set that means A button is pressed). Use Bitwise Operations to retrieve the state of specific buttons.

        -

        If given joypad is outside [0-4] range, returns -1.

        -

        If TAS Editor is not engaged, returns -1.

        -

        -

        -

        taseditor.submitinputchange(int frame, int joypad, int input)

        -


        -

        Sends request to TAS Editor asking to change input of given joypad at given frame.

        -

        Actual movie input won't be changed until the moment you call taseditor.applyinputchanges().

        -

        Using several consecutive requests and then calling applyinputchanges() at the end, you can change several frames of current movie in one moment.

        -

        When applying the pile of requests, TAS Editor will execute them in consecutive order.

        -

        If given frame is negative, TAS Editor will ignore such request.

        -

        If given frame is outside current input range, TAS Editor will expand movie during applyinputchanges() to fit the frame.

        -

        If given joypad is outside [0-4] range, TAS Editor will ignore such request.

        -

        Given input will be treated by TAS Editor as a sequence of bits representing state of each button of given joypad (bit 0 = A, bit 1 = B, bit 2 = Select, bit 3 = Start, bit 4 = Up, bit 5 = Down, bit 6 = Left, bit 7 = Right).

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        taseditor.submitinsertframes(int frame, int number)

        -


        -

        Sends request to TAS Editor asking to insert given number of blank frames before given frame.

        -

        Actual movie won't be changed until the moment you call taseditor.applyinputchanges().

        -

        Insertion can move down some old input and Markers (if "Bind Markers to Input" option is checked by user).

        -

        If given number is less or equal to zero, TAS Editor will ignore such request.

        -

        If given frame is negative, TAS Editor will ignore such request.

        -

        If given frame is outside current input range, TAS Editor will expand movie during applyinputchanges() to fit the frame.

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        taseditor.submitdeleteframes(int frame, int number)

        -


        -

        Sends request to TAS Editor asking to delete given number of frames starting from given frame.

        -

        Actual movie won't be changed until the moment you call taseditor.applyinputchanges().

        -

        Deletion can move up some old input and Markers (if "Bind Markers to Input" option is checked by user).

        -

        If given number is less or equal to zero, TAS Editor will ignore such request.

        -

        If given frame is negative, TAS Editor will ignore such request.

        -

        If given frame is outside current input range, TAS Editor will expand movie during applyinputchanges() to fit the frame.

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        int taseditor.applyinputchanges([string name])

        -


        -

        Instantly applies the list of previously requested changes to current movie. If these requests actually modified movie data, new item will appear in History Log (so user can undo these changes), and Greenzone may become truncated, Playback cursor may lose its position, auto-seeking may be triggered.

        -

        Returns number of frame where first actual changes occurred.

        -

        If no actual changes were found (for example, you asked TAS Editor to set buttons that were already pressed), returns -1.

        -

        If pending list of changes is empty, returns -1.

        -

        You can provide a name that will be assigned to this change. This name will be shown in History Log. If you don't provide a name, TAS Editor will use default name ("Change").

        -

        After applying all requests TAS Editor clears the list of requests.

        -

        If TAS Editor is not engaged, nothing will be done.

        -

        -

        -

        taseditor.clearinputchanges()

        -


        -

        Clears the list of previously requested changes, making TAS Editor forget about them before you call applyinputchanges(). Use this function to discard previously submitted input changes.

        -

        It's also recommended to call this function before making several requests in a row, so that you'll be sure that only your new changes will apply.

        -

        If TAS Editor is not engaged, nothing will be done.

        -


        -


        -


        -


        -


        +

        Returns nil if TAS Editor is not engaged.

        +

        When you want to check Recorder's read-only state, use emu.readonly().

        +


        +

        int taseditor.getsuperimpose()

        +


        +

        Returns number representing current state of Superimpose checkbox in TAS Editor GUI.

        +

        0 – unchecked

        +

        1 – checked

        +

        2 – indeterminate (you can interpret is as half-checked)

        +

        If TAS Editor is not engaged, returns -1.

        +


        +

        int taseditor.getlostplayback()

        +


        +

        Returns the number of the frame where Playback cursor was before input was changed.

        +

        If Playback didn't lose position during Greenzone invalidation, returns -1.

        +

        If TAS Editor is not engaged, returns -1.

        +


        +

        int taseditor.getplaybacktarget()

        +


        +

        If TAS Editor's Playback is currently seeking, returns number of target frame.

        +

        If Playback is not seeking or if TAS Editor is not engaged, returns -1.

        +


        +

        taseditor.setplayback(int frame)

        +


        +

        Sends Playback cursor (current frame counter) to given frame.

        +

        If given frame wasn't found in TAS Editor Greenzone, starts seeking to the frame.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        taseditor.stopseeking()

        +


        +

        Stops Playback seeking and pauses emulation.

        +

        If Playback wasn't seeking, this function only pauses emulation.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        table taseditor.getselection()

        +


        +

        Returns a table (array) containing numbers of currently selected frames. These numbers are sorted in ascending order.

        +

        If no frames are selected at the moment, returns nil.

        +

        If TAS Editor is not engaged, returns nil.

        +


        +

        taseditor.setselection(table new_set)

        +


        +

        Changes current selection to the given set of frames. Frame number in your table don't have to be sorted.

        +

        Call taseditor.setselection(nil) to clear selection.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        int taseditor.getinput(int frame, int joypad)

        +


        +

        Returns a number representing input of given joypad stored in current movie at given frame.

        +

        If given frame is negative, returns -1.

        +

        If given frame is outside current input range, returns 0, which can be interpreted as a blank frame (no buttons pressed at this frame yet).

        +

        Joypad value must be one of the following:

        +

        0 – to get hardware commands (bit 0 = reset, bit 1 = poweron, bit 2 = FDS insert disk, bit 3 = FDS switch side)

        +

        1 – to get 1P buttons (bit 0 = A, bit 1 = B, bit 2 = Select, bit 3 = Start, bit 4 = Up, bit 5 = Down, bit 6 = Left, bit 7 = Right)

        +

        2 – to get 2P buttons

        +

        3 – to get 3P buttons

        +

        4 – to get 4P buttons

        +

        You should handle returned number (if it's not equal to -1) as a byte, each bit corresponds to one button (e.g. if bit 1 is set that means A button is pressed). Use Bitwise Operations to retrieve the state of specific buttons.

        +

        If given joypad is outside [0-4] range, returns -1.

        +

        If TAS Editor is not engaged, returns -1.

        +


        +

        taseditor.submitinputchange(int frame, int joypad, int input)

        +


        +

        Sends request to TAS Editor asking to change input of given joypad at given frame.

        +

        Actual movie input won't be changed until the moment you call taseditor.applyinputchanges().

        +

        Using several consecutive requests and then calling applyinputchanges() at the end, you can change several frames of current movie in one moment.

        +

        When applying the pile of requests, TAS Editor will execute them in consecutive order.

        +

        If given frame is negative, TAS Editor will ignore such request.

        +

        If given frame is outside current input range, TAS Editor will expand movie during applyinputchanges() to fit the frame.

        +

        If given joypad is outside [0-4] range, TAS Editor will ignore such request.

        +

        Given input will be treated by TAS Editor as a sequence of bits representing state of each button of given joypad (bit 0 = A, bit 1 = B, bit 2 = Select, bit 3 = Start, bit 4 = Up, bit 5 = Down, bit 6 = Left, bit 7 = Right).

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        taseditor.submitinsertframes(int frame, int number)

        +


        +

        Sends request to TAS Editor asking to insert given number of blank frames before given frame.

        +

        Actual movie won't be changed until the moment you call taseditor.applyinputchanges().

        +

        Insertion can move down some old input and Markers (if "Bind Markers to Input" option is checked by user).

        +

        If given number is less or equal to zero, TAS Editor will ignore such request.

        +

        If given frame is negative, TAS Editor will ignore such request.

        +

        If given frame is outside current input range, TAS Editor will expand movie during applyinputchanges() to fit the frame.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        taseditor.submitdeleteframes(int frame, int number)

        +


        +

        Sends request to TAS Editor asking to delete given number of frames starting from given frame.

        +

        Actual movie won't be changed until the moment you call taseditor.applyinputchanges().

        +

        Deletion can move up some old input and Markers (if "Bind Markers to Input" option is checked by user).

        +

        If given number is less or equal to zero, TAS Editor will ignore such request.

        +

        If given frame is negative, TAS Editor will ignore such request.

        +

        If given frame is outside current input range, TAS Editor will expand movie during applyinputchanges() to fit the frame.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        int taseditor.applyinputchanges([string name])

        +


        +

        Instantly applies the list of previously requested changes to current movie. If these requests actually modified movie data, new item will appear in History Log (so user can undo these changes), and Greenzone may become truncated, Playback cursor may lose its position, auto-seeking may be triggered.

        +

        Returns number of frame where first actual changes occurred.

        +

        If no actual changes were found (for example, you asked TAS Editor to set buttons that were already pressed), returns -1.

        +

        If pending list of changes is empty, returns -1.

        +

        You can provide a name that will be assigned to this change. This name will be shown in History Log. If you don't provide a name, TAS Editor will use default name ("Change").

        +

        After applying all requests TAS Editor clears the list of requests.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +

        taseditor.clearinputchanges()

        +


        +

        Clears the list of previously requested changes, making TAS Editor forget about them before you call applyinputchanges(). Use this function to discard previously submitted input changes.

        +

        It's also recommended to call this function before making several requests in a row, so that you'll be sure that only your new changes will apply.

        +

        If TAS Editor is not engaged, nothing will be done.

        +


        +


        +


        +


        +


        -

        Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

        -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/MistakeProofing.html b/web/help/taseditor/MistakeProofing.html index b866c164..ad06e008 100644 --- a/web/help/taseditor/MistakeProofing.html +++ b/web/help/taseditor/MistakeProofing.html @@ -1,202 +1,393 @@ - - + + + + + - Mistake-proofing - - - - - - - - - - + + + + + + + + Mistake-proofing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Mistake-proofing

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - -

      -

      Mistake-proofing

      -


      -


      -

      This page lists many small details of implementation that improve interaction between user and the program. All these points must be considered when porting Taseditor to other platforms.

      -


      -
        -
      • When the user closes the emulator, emulator sends a request to Taseditor in order to allow it to close the project first. If the project contains unsaved data, Taseditor shows the Yes/No/Cancel dialog. The user can either save the changes, or save none of them, or cancel the attempt to close the emulator.
      • -
      • When playing back an fm3 project outside Taseditor (like a regular movie), the user can switch the emulator to Recording mode and try rerecording. In this case, the emulator tells the user that current movie is a Taseditor project, and suggests to start editing it. In case of refuse, emulator disables the Recording mode and resumes playing back the project movie. In case of agreement, emulator sends a signal to Taseditor, and at the end of the current frame Taseditor will launch and load the currently played project.
      • -
      • When a ROM is loaded into emulator, the user can launch Taseditor at any moment. If he opens the Taseditor window while playing or recording a movie, Taseditor will automatically create a nameless project containing this movie Input. But if the movie is starting from a savestate, Taseditor will display a warning about not supporting such movies and then create a blank project.
      • -
      • While the project has no name, autosave function doesn't work.
      • -
      • When saving a nameless project, Taseditor suggests the current ROM name as a name for the fm3 project, with the extension changed to .fm3.
      • -
      • Since the FM3 format is a superstructure over the FM2 format, the user can open fm2 files just like Taseditor projects, using the "Open TAS Editor Project" dialog and choosing the filter "All Files (*.*)". When opening fm2 files, Taseditor additionally informs the user about it with the Yes/No dialog. The user can either load the fm2 file as a new project or cancel the loading.
      • -
      • After opening an fm2 file or a corrupted fm3 file, the project is considered nameless, even though the TAS Editor window caption displays the name of the loaded file. At the first saving attempt (Ctrl + S) Taseditor will bring the SaveAs dialog, where the loaded fm2/fm3 file name will be suggested as a name for the project. The user can either save the project with this name or change the name. This way Taseditor draws your attention to the fact that the new project significantly differs from the file that exists on the disk under the same name.
      • -
      • FM3 projects store the version number of the FM3 format used when saving the file. Different versions can be totally or partially incompatible with each other. If the loaded project version doesn't match the currently supported one, Taseditor shows the Yes/No/Cancel dialog. The user can either resume his attempt to load the whole project (not recommended), or load only the Input from the FM2 data (recommended), or cancel loading.
      • -
      • FM2 format (and therefore fm3 too) stores the MD5 checksum of the ROM used when creating the movie/project. When loading a project, Taseditor compares the current ROM checksum with the project's one, and if they don't match, brings the Yes/No dialog, displaying the original and the current ROM names. The user can resume loading or cancel it. Later, when saving this project, Taseditor will notice the checksum mismatch again and suggest replacing the ROM name and the checksum in the file before saving. The user can either approve the replacing, or save the project with the old name and checksum, or cancel the saving.
      • -
      • When loading a corrupted project file, Taseditor tries the best of its ability to prevent emulator crash. If an error is found in the middle of loading, the further loading stops and the rest data is replaced with the default data. Particularly, if the error occurred while loading the Greenzone, the project is left with only the Greenzone frames that were successfully pulled out of the file, the rest frames will be pale. Project loading error messages are logged into the FCEUX Message Log.
      • -
      • When loading a project, Taseditor respects current settings of "Greenzone capacity" and "Undo levels". For example, if while saving a project the Greenzone capacity was 5000, but when loading the project the Greenzone capacity is 3000, some frames will be skipped when loading. It's necessary so that a project saved on a more powerful computer can be opened on a less powerful one, that doesn't have enough memory.
      • -
      • When launching, Taseditor loads the data about patterns from the taseditor_patterns.txt file. If this file cannot be opened (fer example, it was removed), Taseditor creates a small set of default patterns, in order to keep the Patterns menu filled.
      • -
      • Savestates used by the Greenzone differ from regular savestates a bit. They don't contain movie data, because it's useless information for the Greenzone purposes. Besides, they are always compressed, in order to save memory.
      • -
      • If after a Delete or Lua Change operation the user effectively removes all Input from the movie, Taseditor will create one blank frame in the movie beginning.
      • -
      • When user is selecting a range of frames by stretching, it's still possible to use hotkeys with the other hand. To avoid conflict, during DRAG_MODE_SELECTION and DRAG_MODE_DESELECTION some functions related to changing the Selection will not work:
      • -
      -
        -
      • clearSelection()
      • -
      • selectAll()
      • -
      • selectBetweenMarkers()Ctrl + A
      • -
      • selection.undo()Ctrl + Q
      • -
      • selection.redo()Ctrl + W
      • -
      • reselectClipboard()Ctrl + B
      • -
      • selection.Transpose()Ctrl + Up, Ctrl + Down, Ctrl + Home, Ctrl + End
      • -
      • selection.JumpPrevMarker()Ctrl + Page Up
      • -
      • selection.JumpNextMarker()Ctrl + Page Down
      • -
      -
        -
      • Since the icon column is rather narrow, the user may accidentally miss clicking it. So when you click the left border of the Piano Roll or a bit to the left from it, Taseditor assumes that was a click on the icons column. As a result, the user doesn't have to precisely aim when he needs to move the Playback cursor or start dragging it.
      • -
      • When emulator is paused, the middle mouse button works only under condition that the right button is released. Since the middle button is usually a wheel, the user can accidentally push it while rolling the wheel with the right button held (Playback cursor navigation). As for rolling the wheel with modifier keys held, this is used much less often, so they don't need such protection.
      • -
      • Any middleclick over the FCEUX window is sent to Taseditor window. Similarly, the wheel rolling message is sent to Taseditor, when the focus is on the FCEUX window. And the rightclick on the FCEUX window doesn't work at all. Thanks to that, you can use the middle button (the wheel) even when the mouse cursor is over the FCEUX window.
      • -
      • Even when the Recording mode is on, Taseditor won't rerecord Input while seeking. Thanks to that, you can safely drag the Playback cursor without disabling the Recording mode.
      • -
      • When Taseditor is engaged, the following menu commands are available only when the Recording mode if on and the Playback is not seeking:
      • -
      -
        -
      • NES -> Reset
      • -
      • NES -> Power
      • -
      • NES -> Eject/insert Disk
      • -
      • NES -> Switch Disk Side
      • -
      • NES -> Insert Coin
      • -
      -
        -
      • When Taseditor is engaged, the following FCEUX menu commands are unavailable:
      • -
      -
        -
      • File -> Open ROM
      • -
      • File -> Close
      • -
      • File -> Recent
      • -
      • File -> Savestate -> Load State
      • -
      • File -> Savestate -> Save State
      • -
      • File -> Savestate -> Load State From
      • -
      • File -> Savestate -> Save State As
      • -
      • File -> Savestate -> Next save slot
      • -
      • File -> Savestate -> Previous save slot
      • -
      • File -> Savestate -> View save slots
      • -
      • File -> Movie -> Recent
      • -
      • File -> Movie -> Record Movie
      • -
      • File -> Movie -> Play Movie
      • -
      • File -> Movie -> Stop Movie
      • -
      • Config -> Enable -> Auto-savestates (always off when Taseditor is engaged)
      • -
      • Config -> Enable -> Backup Savestates (always off when Taseditor is engaged)
      • -
      • Config -> Enable -> Compress Savestates (always on when Taseditor is engaged)
      • -
      • Config -> PAL Emulation (set up this before launching Taseditor)
      • -
      • Config -> PPU -> New PPU / Old PPU (set up this before launching Taseditor)
      • -
      -
        -
      • It's also necessary to ensure that the user can not change the movie synchronization settings while editing the project. So when Taseditor is engaged, the following GUI elements in the "Input Configuration" window are locked:
      • -
      -
        -
      • the "Attach four-score" checkbox
      • -
      • the "Replace port 2 Start With  Microphone" checkbox
      • -
      • ListBox for port0
      • -
      • ListBox for port1
      • -
      • ListBox for port2
      • -
      -
        -
      • When Taseditor is engaged, the following hotkeys are not working:
      • -
      -
        -
      • Hide Menu Toggle
      • -
      • Fastest Speed
      • -
      • Save State As...
      • -
      • Load State From...
      • -
      • Record Movie To...
      • -
      • Play Movie From...
      • -
      • Stop Movie
      • -
      • Toggle Dipswitch – because these commands are not supported by the FM2 format yet
      • -
      • Load Last Auto-save
      • -
      • View save slots
      • -
      • Open ROM
      • -
      • Close ROM
      • -
      • Undo/Redo Savestate
      • -
      • Toggle Fullscreen
      • -
      -
        -
      • Hotkeys that change their behavior when Taseditor is engaged:
      • -
      -
        -
      • Power
      • -
      • Reset
      • -
      • Eject or Insert FDS Disk
      • -
      • Switch FDS Disk Side
      • -
      • Insert Coin
      • -
      • Savestate Slot 0Savestate Slot 9
      • -
      • Save State
      • -
      • Save State to Slot 0Save State to Slot 9
      • -
      • Load State
      • -
      • Load State from Slot 0Load State from Slot 9
      • -
      • Play Movie From Beginning
      • -
      • Reload ROM or TAS Editor Project
      • -
      • Open TAS Editor
      • -
      -
        -
      • Since the Alt and F10 keys are actively used in Taseditor work, their standard behavior (open main menu) is disabled.
      • -
      • Since the Spacebar key is used as a hotkey by default, its standard behavior (simulate the click on the currently focused GUI element) is disabled. Also, all GUI elements of the TAS Editor window handle the middleclick message and send it to the Playback, thus the middleclick works independently of the mouse cursor position.
      • -
      • Since the context menu on the rightclick at the Piano Roll is not often used, it appears only if the user clicks the selected line in the frame number column (Frame#). In all the rest cases the context menu doesn't appear, instead the rightclick-and-hold at the Piano Roll allows to drag its contents in any direction.
      • -
      • Since the right button is often used for the Playback cursor navigation with the wheel, the user is encouraged to click it without caring about the current mouse cursor position. In theory it's possible that the user accidentally rightclicks a Bookmark. To avoid such unintended commands, the Bookmark List and the Branches Tree both require to press and release the right button over the same Bookmark. Also, if between pressing and releasing the user rotated the wheel, the Bookmark won't be changed.
      • -
      • The user can jump to a Bookmark with a single click on the desired icon in the Branches Tree. Doing so he expects that after the click the light-blue triangle (the Playback cursor icon) will also jump to the place in the Branches Tree. It is indeed so for Bookmarks that don't contradict with the current timeline, but it's not so for Bookmarks representing alternative strategies. After jumping to the frame of such Bookmark, the Playback cursor will appear on another branch (even though it's on the same frame of the movie). To notify the user about possible misconception, the mouse cursor turns into an arrow with a question mark when the user points to such Bookmarks.
      • -
      • While the Branches Tree is transforming, hovering the mouse cursor over its elements doesn't work, because the active element area is constantly moving and running away from the mouse cursor.
      • -
      -


      -


      -


      -


      -


      -

      -

      Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

      -
      - - - - + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Mistake-proofing

      + +
      + +

      +

      Mistake-proofing

      +


      +


      +

      This page lists many small details of implementation that improve interaction between user and the program. All these points must be considered when porting Taseditor to other platforms.

      +


      +
        +
      • When the user closes the emulator, emulator sends a request to Taseditor in order to allow it to close the project first. If the project contains unsaved data, Taseditor shows the Yes/No/Cancel dialog. The user can either save the changes, or save none of them, or cancel the attempt to close the emulator.
      • +
      • When playing back an fm3 project outside Taseditor (like a regular movie), the user can switch the emulator to Recording mode and try rerecording. In this case, the emulator tells the user that current movie is a Taseditor project, and suggests to start editing it. In case of refuse, emulator disables the Recording mode and resumes playing back the project movie. In case of agreement, emulator sends a signal to Taseditor, and at the end of the current frame Taseditor will launch and load the currently played project.
      • +
      • When a ROM is loaded into emulator, the user can launch Taseditor at any moment. If he opens the Taseditor window while playing or recording a movie, Taseditor will automatically create a nameless project containing this movie Input. But if the movie is starting from a savestate, Taseditor will display a warning about not supporting such movies and then create a blank project.
      • +
      • While the project has no name, autosave function doesn't work.
      • +
      • When saving a nameless project, Taseditor suggests the current ROM name as a name for the fm3 project, with the extension changed to .fm3.
      • +
      • Since the FM3 format is a superstructure over the FM2 format, the user can open fm2 files just like Taseditor projects, using the "Open TAS Editor Project" dialog and choosing the filter "All Files (*.*)". When opening fm2 files, Taseditor additionally informs the user about it with the Yes/No dialog. The user can either load the fm2 file as a new project or cancel the loading.
      • +
      • After opening an fm2 file or a corrupted fm3 file, the project is considered nameless, even though the TAS Editor window caption displays the name of the loaded file. At the first saving attempt (Ctrl + S) Taseditor will bring the SaveAs dialog, where the loaded fm2/fm3 file name will be suggested as a name for the project. The user can either save the project with this name or change the name. This way Taseditor draws your attention to the fact that the new project significantly differs from the file that exists on the disk under the same name.
      • +
      • FM3 projects store the version number of the FM3 format used when saving the file. Different versions can be totally or partially incompatible with each other. If the loaded project version doesn't match the currently supported one, Taseditor shows the Yes/No/Cancel dialog. The user can either resume his attempt to load the whole project (not recommended), or load only the Input from the FM2 data (recommended), or cancel loading.
      • +
      • FM2 format (and therefore fm3 too) stores the MD5 checksum of the ROM used when creating the movie/project. When loading a project, Taseditor compares the current ROM checksum with the project's one, and if they don't match, brings the Yes/No dialog, displaying the original and the current ROM names. The user can resume loading or cancel it. Later, when saving this project, Taseditor will notice the checksum mismatch again and suggest replacing the ROM name and the checksum in the file before saving. The user can either approve the replacing, or save the project with the old name and checksum, or cancel the saving.
      • +
      • When loading a corrupted project file, Taseditor tries the best of its ability to prevent emulator crash. If an error is found in the middle of loading, the further loading stops and the rest data is replaced with the default data. Particularly, if the error occurred while loading the Greenzone, the project is left with only the Greenzone frames that were successfully pulled out of the file, the rest frames will be pale. Project loading error messages are logged into the FCEUX Message Log.
      • +
      • When loading a project, Taseditor respects current settings of "Greenzone capacity" and "Undo levels". For example, if while saving a project the Greenzone capacity was 5000, but when loading the project the Greenzone capacity is 3000, some frames will be skipped when loading. It's necessary so that a project saved on a more powerful computer can be opened on a less powerful one, that doesn't have enough memory.
      • +
      • When launching, Taseditor loads the data about patterns from the taseditor_patterns.txt file. If this file cannot be opened (fer example, it was removed), Taseditor creates a small set of default patterns, in order to keep the Patterns menu filled.
      • +
      • Savestates used by the Greenzone differ from regular savestates a bit. They don't contain movie data, because it's useless information for the Greenzone purposes. Besides, they are always compressed, in order to save memory.
      • +
      • If after a Delete or Lua Change operation the user effectively removes all Input from the movie, Taseditor will create one blank frame in the movie beginning.
      • +
      • When user is selecting a range of frames by stretching, it's still possible to use hotkeys with the other hand. To avoid conflict, during DRAG_MODE_SELECTION and DRAG_MODE_DESELECTION some functions related to changing the Selection will not work:
      • +
      +
        +
      • clearSelection()
      • +
      • selectAll()
      • +
      • selectBetweenMarkers()Ctrl + A
      • +
      • selection.undo()Ctrl + Q
      • +
      • selection.redo()Ctrl + W
      • +
      • reselectClipboard()Ctrl + B
      • +
      • selection.Transpose()Ctrl + Up, Ctrl + Down, Ctrl + Home, Ctrl + End
      • +
      • selection.JumpPrevMarker()Ctrl + Page Up
      • +
      • selection.JumpNextMarker()Ctrl + Page Down
      • +
      +
        +
      • Since the icon column is rather narrow, the user may accidentally miss clicking it. So when you click the left border of the Piano Roll or a bit to the left from it, Taseditor assumes that was a click on the icons column. As a result, the user doesn't have to precisely aim when he needs to move the Playback cursor or start dragging it.
      • +
      • When emulator is paused, the middle mouse button works only under condition that the right button is released. Since the middle button is usually a wheel, the user can accidentally push it while rolling the wheel with the right button held (Playback cursor navigation). As for rolling the wheel with modifier keys held, this is used much less often, so they don't need such protection.
      • +
      • Any middleclick over the FCEUX window is sent to Taseditor window. Similarly, the wheel rolling message is sent to Taseditor, when the focus is on the FCEUX window. And the rightclick on the FCEUX window doesn't work at all. Thanks to that, you can use the middle button (the wheel) even when the mouse cursor is over the FCEUX window.
      • +
      • Even when the Recording mode is on, Taseditor won't rerecord Input while seeking. Thanks to that, you can safely drag the Playback cursor without disabling the Recording mode.
      • +
      • When Taseditor is engaged, the following menu commands are available only when the Recording mode if on and the Playback is not seeking:
      • +
      +
        +
      • NES -> Reset
      • +
      • NES -> Power
      • +
      • NES -> Eject/insert Disk
      • +
      • NES -> Switch Disk Side
      • +
      • NES -> Insert Coin
      • +
      +
        +
      • When Taseditor is engaged, the following FCEUX menu commands are unavailable:
      • +
      +
        +
      • File -> Open ROM
      • +
      • File -> Close
      • +
      • File -> Recent
      • +
      • File -> Savestate -> Load State
      • +
      • File -> Savestate -> Save State
      • +
      • File -> Savestate -> Load State From
      • +
      • File -> Savestate -> Save State As
      • +
      • File -> Savestate -> Next save slot
      • +
      • File -> Savestate -> Previous save slot
      • +
      • File -> Savestate -> View save slots
      • +
      • File -> Movie -> Recent
      • +
      • File -> Movie -> Record Movie
      • +
      • File -> Movie -> Play Movie
      • +
      • File -> Movie -> Stop Movie
      • +
      • Config -> Enable -> Auto-savestates (always off when Taseditor is engaged)
      • +
      • Config -> Enable -> Backup Savestates (always off when Taseditor is engaged)
      • +
      • Config -> Enable -> Compress Savestates (always on when Taseditor is engaged)
      • +
      • Config -> PAL Emulation (set up this before launching Taseditor)
      • +
      • Config -> PPU -> New PPU / Old PPU (set up this before launching Taseditor)
      • +
      +
        +
      • It's also necessary to ensure that the user can not change the movie synchronization settings while editing the project. So when Taseditor is engaged, the following GUI elements in the "Input Configuration" window are locked:
      • +
      +
        +
      • the "Attach four-score" checkbox
      • +
      • the "Replace port 2 Start With  Microphone" checkbox
      • +
      • ListBox for port0
      • +
      • ListBox for port1
      • +
      • ListBox for port2
      • +
      +
        +
      • When Taseditor is engaged, the following hotkeys are not working:
      • +
      +
        +
      • Hide Menu Toggle
      • +
      • Fastest Speed
      • +
      • Save State As...
      • +
      • Load State From...
      • +
      • Record Movie To...
      • +
      • Play Movie From...
      • +
      • Stop Movie
      • +
      • Toggle Dipswitch – because these commands are not supported by the FM2 format yet
      • +
      • Load Last Auto-save
      • +
      • View save slots
      • +
      • Open ROM
      • +
      • Close ROM
      • +
      • Undo/Redo Savestate
      • +
      • Toggle Fullscreen
      • +
      +
        +
      • Hotkeys that change their behavior when Taseditor is engaged:
      • +
      +
        +
      • Power
      • +
      • Reset
      • +
      • Eject or Insert FDS Disk
      • +
      • Switch FDS Disk Side
      • +
      • Insert Coin
      • +
      • Savestate Slot 0Savestate Slot 9
      • +
      • Save State
      • +
      • Save State to Slot 0Save State to Slot 9
      • +
      • Load State
      • +
      • Load State from Slot 0Load State from Slot 9
      • +
      • Play Movie From Beginning
      • +
      • Reload ROM or TAS Editor Project
      • +
      • Open TAS Editor
      • +
      +
        +
      • Since the Alt and F10 keys are actively used in Taseditor work, their standard behavior (open main menu) is disabled.
      • +
      • Since the Spacebar key is used as a hotkey by default, its standard behavior (simulate the click on the currently focused GUI element) is disabled. Also, all GUI elements of the TAS Editor window handle the middleclick message and send it to the Playback, thus the middleclick works independently of the mouse cursor position.
      • +
      • Since the context menu on the rightclick at the Piano Roll is not often used, it appears only if the user clicks the selected line in the frame number column (Frame#). In all the rest cases the context menu doesn't appear, instead the rightclick-and-hold at the Piano Roll allows to drag its contents in any direction.
      • +
      • Since the right button is often used for the Playback cursor navigation with the wheel, the user is encouraged to click it without caring about the current mouse cursor position. In theory it's possible that the user accidentally rightclicks a Bookmark. To avoid such unintended commands, the Bookmark List and the Branches Tree both require to press and release the right button over the same Bookmark. Also, if between pressing and releasing the user rotated the wheel, the Bookmark won't be changed.
      • +
      • The user can jump to a Bookmark with a single click on the desired icon in the Branches Tree. Doing so he expects that after the click the light-blue triangle (the Playback cursor icon) will also jump to the place in the Branches Tree. It is indeed so for Bookmarks that don't contradict with the current timeline, but it's not so for Bookmarks representing alternative strategies. After jumping to the frame of such Bookmark, the Playback cursor will appear on another branch (even though it's on the same frame of the movie). To notify the user about possible misconception, the mouse cursor turns into an arrow with a question mark when the user points to such Bookmarks.
      • +
      • While the Branches Tree is transforming, hovering the mouse cursor over its elements doesn't work, because the active element area is constantly moving and running away from the mouse cursor.
      • +
      +


      +


      +


      +


      +


      +

      +

      Created with the Personal Edition of HelpNDoc: Full-featured EPub generator

      + +
      + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/taseditor/Navigation.html b/web/help/taseditor/Navigation.html index a8c12194..821fc4d0 100644 --- a/web/help/taseditor/Navigation.html +++ b/web/help/taseditor/Navigation.html @@ -1,373 +1,538 @@ - - + + + + + - Navigation - - - - - - - - - - + + + + + + + + Navigation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Navigation

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Navigation

      + +
      +

      -

      Navigation

      +

      Navigation



      -

      Emulator's main window can only display data of a single frame of the movie at any given moment.

      -

      The Piano Roll can cover data for tens of frames at the same time.

      -

      But an average movie has tens of thousands of frames. So TASer must often scroll the Piano Roll up and down to see the data about needed segment, and rewind emulator playback to see the data about needed frame.

      -

      Throughout the documentation this behavior is called "movie navigation". It takes major part of TASing, and Taseditor introduces many new ways of navigation, striving to make it as fast as possible. Depending on the situation some of them are better then others, so it's not recommended to stick to a single method.

      -

      Ideally, the navigation skills should move to your muscle memory, allowing you to always appear at the necessary place of the movie without interrupting the mental analysis of the current task.

      -


      -

      All ways of navigating a movie:

      -


      -
        -
      • Scrolling the Piano Roll
      • +

        Emulator's main window can only display data of a single frame of the movie at any given moment.

        +

        The Piano Roll can cover data for tens of frames at the same time.

        +

        But an average movie has tens of thousands of frames. So TASer must often scroll the Piano Roll up and down to see the data about needed segment, and rewind emulator playback to see the data about needed frame.

        +

        Throughout the documentation this behavior is called "movie navigation". It takes major part of TASing, and Taseditor introduces many new ways of navigation, striving to make it as fast as possible. Depending on the situation some of them are better then others, so it's not recommended to stick to a single method.

        +

        Ideally, the navigation skills should move to your muscle memory, allowing you to always appear at the necessary place of the movie without interrupting the mental analysis of the current task.

        +


        +

        All ways of navigating a movie:

        +


        + -
          -
        1. Using vertical scrollbar
        2. -
        3. Rolling mouse wheel
        4. -
        5. Crossing gaps
        6. -
        7. Paging through
        8. -
        9. Jumping to the beginning / to the end of the movie
        10. -
        11. Jumping to the Playback cursor
        12. -
        13. Jumping to the Selection cursor
        14. -
        15. Jumping to the Marker above Playback cursor
        16. -
        17. Jumping to the Marker above Selection cursor
        18. +
            +
          1. Using vertical scrollbar
          2. +
          3. Rolling mouse wheel
          4. +
          5. Crossing gaps
          6. +
          7. Paging through
          8. +
          9. Jumping to the beginning / to the end of the movie
          10. +
          11. Jumping to the Playback cursor
          12. +
          13. Jumping to the Selection cursor
          14. +
          15. Jumping to the Marker above Playback cursor
          16. +
          17. Jumping to the Marker above Selection cursor
          -
            -
          • Playback cursor navigation
          • + -
              -
            1. Frame-by-frame shift
            2. -
            3. Rewinding by mouse wheel
            4. -
            5. Dragging with mouse
            6. -
            7. Jumping on Markers
            8. -
            9. Jumping to Bookmarks
            10. -
            11. Jumping to the beginning / to the end of the movie
            12. +
                +
              1. Frame-by-frame shift
              2. +
              3. Rewinding by mouse wheel
              4. +
              5. Dragging with mouse
              6. +
              7. Jumping on Markers
              8. +
              9. Jumping to Bookmarks
              10. +
              11. Jumping to the beginning / to the end of the movie
              -
                -
              • Selection cursor navigation
              • + -
                  -
                1. Frame-by-frame shift
                2. -
                3. Moving Selection to the beginning / to the end of the movie
                4. -
                5. Jumping on Markers
                6. -
                7. Tracking the Selection History
                8. -
                9. Returning to the origin of Clipboard data
                10. +
                    +
                  1. Frame-by-frame shift
                  2. +
                  3. Moving Selection to the beginning / to the end of the movie
                  4. +
                  5. Jumping on Markers
                  6. +
                  7. Tracking the Selection History
                  8. +
                  9. Returning to the origin of Clipboard data
                  -
                    -
                  • Special
                  • + -
                      -
                    1. Finding Markers with a given text
                    2. -
                    3. Jumping to segment with similar description
                    4. +
                        +
                      1. Finding Markers with a given text
                      2. +
                      3. Jumping to segment with similar description
                      -


                      -
                      -

                      -

                      -

                      Scrolling the Piano Roll

                      -


                      -

                      -

                      -

                      1. Using vertical scrollbar

                      -


                      -

                      Click on the scrollbar or drag its thumb to scroll the Piano Roll like any other list.

                      -

                      Playback cursor and Selection cursor positions are not affected by the Piano Roll scrolling.

                      -

                      When to use:

                      -
                        -
                      • when you need to get to a far away section of the movie. The scrollbar allows to traverse thousands of frames at once
                      • -
                      • when you're searching for a segment which can be anywhere in the movie
                      • +


                        +
                        +


                        +

                        Scrolling the Piano Roll

                        +


                        +


                        +

                        1. Using vertical scrollbar

                        +


                        +

                        Click on the scrollbar or drag its thumb to scroll the Piano Roll like any other list.

                        +

                        Playback cursor and Selection cursor positions are not affected by the Piano Roll scrolling.

                        +

                        When to use:

                        +
                          +
                        • when you need to get to a far away section of the movie. The scrollbar allows to traverse thousands of frames at once
                        • +
                        • when you're searching for a segment which can be anywhere in the movie
                        -

                        -

                        -

                        2. Rolling mouse wheel

                        -


                        -

                        Roll mouse wheel up or down to scroll the Piano Roll like any other list.

                        -

                        The mouse cursor can be pointing anywhere, except History Log window.

                        -

                        When to use:

                        -
                          -
                        • when you're observing a segment that doesn't fit into the Piano Roll visible area
                        • -
                        • when you're searching for a nearby segment
                        • +


                          +

                          2. Rolling mouse wheel

                          +


                          +

                          Roll mouse wheel up or down to scroll the Piano Roll like any other list.

                          +

                          The mouse cursor can be pointing anywhere, except History Log window.

                          +

                          When to use:

                          +
                            +
                          • when you're observing a segment that doesn't fit into the Piano Roll visible area
                          • +
                          • when you're searching for a nearby segment
                          -

                          -

                          -

                          3. Crossing gaps

                          -


                          -

                          Point mouse cursor to any cell in Input/Markers/icons, hold Alt and roll the mouse wheel up or down to scroll the Piano Roll to the closest cell that contains a data different from the data of adjacent cell.

                          -

                          When to use:

                          -
                            -
                          • when you see an emptiness in specific button column and you want to find the nearest frame where the button becomes pressed
                          • -
                          • when you see the specific button is held for many frames and you want to find exactly the first frame where the button was pressed, or the frame where it will be released
                          • -
                          • when you need to find previous/next Marker
                          • -
                          • when you need to find previous/next buttonpress
                          • -
                          • when you need to find the Bookmark above/below (in the icons column)
                          • +


                            +

                            3. Crossing gaps

                            +


                            +

                            Point mouse cursor to any cell in Input/Markers/icons, hold Alt and roll the mouse wheel up or down to scroll the Piano Roll to the closest cell that contains a data different from the data of adjacent cell.

                            +

                            When to use:

                            +
                              +
                            • when you see an emptiness in specific button column and you want to find the nearest frame where the button becomes pressed
                            • +
                            • when you see the specific button is held for many frames and you want to find exactly the first frame where the button was pressed, or the frame where it will be released
                            • +
                            • when you need to find previous/next Marker
                            • +
                            • when you need to find previous/next buttonpress
                            • +
                            • when you need to find the Bookmark above/below (in the icons column)
                            -

                            -

                            -

                            4. Paging through

                            -


                            -

                            Press Page Up or Page Down key to scroll the Piano Roll like any other list. The amount of scrolling depends on the size of the Piano Roll visible area.

                            -

                            When to use:

                            -
                              -
                            • when you're searching for a segment which is likely somewhere nearby
                            • +


                              +

                              4. Paging through

                              +


                              +

                              Press Page Up or Page Down key to scroll the Piano Roll like any other list. The amount of scrolling depends on the size of the Piano Roll visible area.

                              +

                              When to use:

                              +
                                +
                              • when you're searching for a segment which is likely somewhere nearby
                              -

                              -

                              -

                              5. Jumping to the beginning / to the end of the movie

                              -


                              -

                              Press Home or End to scroll Piano Roll to the beginning or to the end of the movie.

                              -

                              When to use:

                              -
                                -
                              • when you need to observe the beginning or the end of the movie
                              • +


                                +

                                5. Jumping to the beginning / to the end of the movie

                                +


                                +

                                Press Home or End to scroll Piano Roll to the beginning or to the end of the movie.

                                +

                                When to use:

                                +
                                  +
                                • when you need to observe the beginning or the end of the movie
                                -

                                -

                                -

                                6. Jumping to the Playback cursor

                                -


                                -

                                Click on the upper "Marker #" label (colored light-blue) to immediately scroll the Piano Roll to the Playback cursor position. Alternative way to do it is to press Shift key twice within a short amount of time.

                                -

                                When to use:

                                -
                                  -
                                • when you need to see the context of currently played frame of the movie
                                • -
                                • when you wish to return to the currently played segment from any other place
                                • +


                                  +

                                  6. Jumping to the Playback cursor

                                  +


                                  +

                                  Click on the upper "Marker #" label (colored light-blue) to immediately scroll the Piano Roll to the Playback cursor position. Alternative way to do it is to press Shift key twice within a short amount of time.

                                  +

                                  When to use:

                                  +
                                    +
                                  • when you need to see the context of currently played frame of the movie
                                  • +
                                  • when you wish to return to the currently played segment from any other place
                                  -

                                  -

                                  -

                                  7. Jumping to the Selection cursor

                                  -


                                  -

                                  Click on the lower "Marker #" label to immediately scroll the Piano Roll to the Selection cursor position. Alternative way to do it is to press Ctrl key twice within a short amount of time.

                                  -

                                  When to use:

                                  -
                                    -
                                  • when you wish to return to the currently edited segment from any other place
                                  • +


                                    +

                                    7. Jumping to the Selection cursor

                                    +


                                    +

                                    Click on the lower "Marker #" label to immediately scroll the Piano Roll to the Selection cursor position. Alternative way to do it is to press Ctrl key twice within a short amount of time.

                                    +

                                    When to use:

                                    +
                                      +
                                    • when you wish to return to the currently edited segment from any other place
                                    -

                                    -

                                    -

                                    8. Jumping to the Marker above Playback cursor

                                    -


                                    -

                                    Click on the upper edit field to immediately scroll the Piano Roll to the Marker which Note is going to be edited.

                                    -

                                    Works only when the View -> Follow Marker Note context option is enabled.

                                    -

                                    When to use:

                                    -
                                      -
                                    • when you need to see the beginning of the currently played segment
                                    • +


                                      +

                                      8. Jumping to the Marker above Playback cursor

                                      +


                                      +

                                      Click on the upper edit field to immediately scroll the Piano Roll to the Marker which Note is going to be edited.

                                      +

                                      Works only when the View -> Follow Marker Note context option is enabled.

                                      +

                                      When to use:

                                      +
                                        +
                                      • when you need to see the beginning of the currently played segment
                                      -

                                      -

                                      -

                                      9. Jumping to the Marker above Selection cursor

                                      -


                                      -

                                      Click on the lower edit field to immediately scroll the Piano Roll to the Marker which Note is going to be edited.

                                      -

                                      Works only when the View -> Follow Marker Note context option is enabled.

                                      -

                                      When to use:

                                      -
                                        -
                                      • when you need to see the beginning of the currently edited segment
                                      • +


                                        +

                                        9. Jumping to the Marker above Selection cursor

                                        +


                                        +

                                        Click on the lower edit field to immediately scroll the Piano Roll to the Marker which Note is going to be edited.

                                        +

                                        Works only when the View -> Follow Marker Note context option is enabled.

                                        +

                                        When to use:

                                        +
                                          +
                                        • when you need to see the beginning of the currently edited segment
                                        -


                                        -

                                        -

                                        -

                                        Playback cursor navigation

                                        -


                                        -

                                        The Playback cursor is always bound to current state of emulated game. This means that emulator affects this cursor when emulating the game, and vice versa, when you move this cursor, you affect the emulator.

                                        -

                                        There's one limitation in the controlling of the cursor: sometimes it can't immediately move to the desired frame, seeking takes some time.

                                        -

                                        When the "Follow cursor" checkbox in the Playback panel is checked, the Piano Roll automatically scrolls after the Playback cursor (except when seeking).

                                        -

                                        -

                                        -

                                        1. Frame-by-frame shift

                                        -


                                        -

                                        Click on < or > button in the Playback panel, or press Shift + Up or Shift + Down, or use Frame Rewind or Frame Advance hotkey to move the Playback cursor 1 frame back of forward.

                                        -

                                        When to use:

                                        -
                                          -
                                        • when you need to explore events of current segment carefully
                                        • +


                                          +


                                          +

                                          Playback cursor navigation

                                          +


                                          +

                                          The Playback cursor is always bound to current state of emulated game. This means that emulator affects this cursor when emulating the game, and vice versa, when you move this cursor, you affect the emulator.

                                          +

                                          There's one limitation in the controlling of the cursor: sometimes it can't immediately move to the desired frame, seeking takes some time.

                                          +

                                          When the "Follow cursor" checkbox in the Playback panel is checked, the Piano Roll automatically scrolls after the Playback cursor (except when seeking).

                                          +


                                          +

                                          1. Frame-by-frame shift

                                          +


                                          +

                                          Click on < or > button in the Playback panel, or press Shift + Up or Shift + Down, or use Frame Rewind or Frame Advance hotkey to move the Playback cursor 1 frame back of forward.

                                          +

                                          When to use:

                                          +
                                            +
                                          • when you need to explore events of current segment carefully
                                          -

                                          -

                                          -

                                          2. Rewinding by mouse wheel

                                          -


                                          -

                                          Hold the right mouse button and roll mouse wheel up or down to move the Playback cursor.

                                          -

                                          The mouse cursor can be pointing anywhere.

                                          -

                                          When to use:

                                          -
                                            -
                                          • when you need to explore events of current segment carefully/quickly
                                          • +


                                            +

                                            2. Rewinding by mouse wheel

                                            +


                                            +

                                            Hold the right mouse button and roll mouse wheel up or down to move the Playback cursor.

                                            +

                                            The mouse cursor can be pointing anywhere.

                                            +

                                            When to use:

                                            +
                                              +
                                            • when you need to explore events of current segment carefully/quickly
                                            -

                                            -

                                            -

                                            3. Dragging with mouse

                                            -


                                            -

                                            Click on any cell in the leftmost column of the Piano Roll ("Icons" column) to send the Playback cursor to the frame. Also, click on any cell of the column and hold the left mouse button to drag the Playback cursor by moving the mouse. This method also allows to scroll the Piano Roll by dragging the Playback cursor outside (above or below the Piano Roll).

                                            -

                                            When to use:

                                            -
                                              -
                                            • when you're searching for an in-game event of the movie
                                            • +


                                              +

                                              3. Dragging with mouse

                                              +


                                              +

                                              Click on any cell in the leftmost column of the Piano Roll ("Icons" column) to send the Playback cursor to the frame. Also, click on any cell of the column and hold the left mouse button to drag the Playback cursor by moving the mouse. This method also allows to scroll the Piano Roll by dragging the Playback cursor outside (above or below the Piano Roll).

                                              +

                                              When to use:

                                              +
                                                +
                                              • when you're searching for an in-game event of the movie
                                              -

                                              -

                                              -

                                              4. Jumping on Markers

                                              -


                                              -

                                              Click on << or >> button in the Playback panel, or press Shift + Page Up or Shift + Page Down, or hold Shift and roll the mouse wheel to move the Playback cursor to previous or next Marker.

                                              -

                                              When to use:

                                              -
                                                -
                                              • when you need to set the Playback cursor to the beginning of currently played segment (provided that the frame of the beginning is marked)
                                              • -
                                              • when you want to see events of previous/next segments
                                              • +


                                                +

                                                4. Jumping on Markers

                                                +


                                                +

                                                Click on << or >> button in the Playback panel, or press Shift + Page Up or Shift + Page Down, or hold Shift and roll the mouse wheel to move the Playback cursor to previous or next Marker.

                                                +

                                                When to use:

                                                +
                                                  +
                                                • when you need to set the Playback cursor to the beginning of currently played segment (provided that the frame of the beginning is marked)
                                                • +
                                                • when you want to see events of previous/next segments
                                                -

                                                -

                                                -

                                                5. Jumping to Bookmarks

                                                -


                                                -

                                                Press the hotkey (0-9) corresponding to the number of desired Bookmark, or click on a frame number in Bookmarks List, or click on a Bookmark icon in the Branches Tree to send the Playback cursor to the bookmarked frame.

                                                -

                                                When to use:

                                                -
                                                  -
                                                • when you need to re-watch events of the movie starting from a bookmarked frame (e.g. watch the movie from the beginning of Level 2)
                                                • -
                                                • when you changed Input before the bookmarked frame and want to see new events at the frame
                                                • +


                                                  +

                                                  5. Jumping to Bookmarks

                                                  +


                                                  +

                                                  Press the hotkey (0-9) corresponding to the number of desired Bookmark, or click on a frame number in Bookmarks List, or click on a Bookmark icon in the Branches Tree to send the Playback cursor to the bookmarked frame.

                                                  +

                                                  When to use:

                                                  +
                                                    +
                                                  • when you need to re-watch events of the movie starting from a bookmarked frame (e.g. watch the movie from the beginning of Level 2)
                                                  • +
                                                  • when you changed Input before the bookmarked frame and want to see new events at the frame
                                                  -

                                                  -

                                                  -

                                                  6. Jumping to the beginning / to the end of the movie

                                                  -


                                                  -

                                                  Press Shift + Home or Shift + End, or click the cloudlet or the fireball in the Branches Tree to move the Playback cursor to the beginning or to the end of the movie.

                                                  -

                                                  You can also press the Play movie from the beginning hotkey (Shift + R by default) to move the Playback cursor to the beginning of the movie.

                                                  -

                                                  When to use:

                                                  -
                                                    -
                                                  • when you want to watch the movie from the very beginning
                                                  • -
                                                  • when you need to fill all movie frames with Greenzone data
                                                  • +


                                                    +

                                                    6. Jumping to the beginning / to the end of the movie

                                                    +


                                                    +

                                                    Press Shift + Home or Shift + End, or click the cloudlet or the fireball in the Branches Tree to move the Playback cursor to the beginning or to the end of the movie.

                                                    +

                                                    You can also press the Play movie from the beginning hotkey (Shift + R by default) to move the Playback cursor to the beginning of the movie.

                                                    +

                                                    When to use:

                                                    +
                                                      +
                                                    • when you want to watch the movie from the very beginning
                                                    • +
                                                    • when you need to fill all movie frames with Greenzone data
                                                    -


                                                    -

                                                    -

                                                    -

                                                    Selection cursor navigation

                                                    -


                                                    -

                                                    Selection cursor is usually located on the frame where the most recent changes of Input were made, but you can also move the cursor to any other frame when needed.

                                                    -

                                                    The Piano Roll automatically scrolls after the Selection.

                                                    -

                                                    -

                                                    -

                                                    1. Frame-by-frame shift

                                                    -


                                                    -

                                                    Press Ctrl + Up or Ctrl + Down to move current Selection 1 frame up or down.

                                                    -

                                                    When to use:

                                                    -
                                                      -
                                                    • when you need to transpose Selection up or down
                                                    • +


                                                      +


                                                      +

                                                      Selection cursor navigation

                                                      +


                                                      +

                                                      Selection cursor is usually located on the frame where the most recent changes of Input were made, but you can also move the cursor to any other frame when needed.

                                                      +

                                                      The Piano Roll automatically scrolls after the Selection.

                                                      +


                                                      +

                                                      1. Frame-by-frame shift

                                                      +


                                                      +

                                                      Press Ctrl + Up or Ctrl + Down to move current Selection 1 frame up or down.

                                                      +

                                                      When to use:

                                                      +
                                                        +
                                                      • when you need to transpose Selection up or down
                                                      -

                                                      -

                                                      -

                                                      2. Moving Selection to the beginning / to the end of the movie

                                                      -


                                                      -

                                                      Press Ctrl + Home or Ctrl + End to move current Selection to the beginning or to the end of the movie.

                                                      -

                                                      When to use:

                                                      -
                                                        -
                                                      • when you need to select the same set of frames at the beginning or at the end of the movie
                                                      • +


                                                        +

                                                        2. Moving Selection to the beginning / to the end of the movie

                                                        +


                                                        +

                                                        Press Ctrl + Home or Ctrl + End to move current Selection to the beginning or to the end of the movie.

                                                        +

                                                        When to use:

                                                        +
                                                          +
                                                        • when you need to select the same set of frames at the beginning or at the end of the movie
                                                        -

                                                        -

                                                        -

                                                        3. Jumping on Markers

                                                        -


                                                        -

                                                        Click on << or >> button at the bottom of the Toolbox, or press Ctrl + Page Up or Ctrl + Page Down, or hold Ctrl and roll the mouse wheel to move Selection cursor to previous or next Marker.

                                                        -

                                                        When to use:

                                                        -
                                                          -
                                                        • when you need to set the Selection cursor to the beginning of currently edited segment (provided that the frame of the beginning is marked)
                                                        • -
                                                        • when you want to move to previous/next segments
                                                        • +


                                                          +

                                                          3. Jumping on Markers

                                                          +


                                                          +

                                                          Click on << or >> button at the bottom of the Toolbox, or press Ctrl + Page Up or Ctrl + Page Down, or hold Ctrl and roll the mouse wheel to move Selection cursor to previous or next Marker.

                                                          +

                                                          When to use:

                                                          +
                                                            +
                                                          • when you need to set the Selection cursor to the beginning of currently edited segment (provided that the frame of the beginning is marked)
                                                          • +
                                                          • when you want to move to previous/next segments
                                                          -

                                                          -

                                                          -

                                                          4. Tracking the Selection History

                                                          -


                                                          -

                                                          Press Ctrl + Q or Ctrl + W to revert Selection to its previous or next state.

                                                          -

                                                          This method of navigation allows to return to previously edited segments and quickly recollect the sequence of recent changes.

                                                          -

                                                          When to use:

                                                          -
                                                            -
                                                          • when you need to return to previously edited segment
                                                          • -
                                                          • when you need to select the same set of frames as before
                                                          • +


                                                            +

                                                            4. Tracking the Selection History

                                                            +


                                                            +

                                                            Press Ctrl + Q or Ctrl + W to revert Selection to its previous or next state.

                                                            +

                                                            This method of navigation allows to return to previously edited segments and quickly recollect the sequence of recent changes. 

                                                            +

                                                            When to use:

                                                            +
                                                              +
                                                            • when you need to return to previously edited segment
                                                            • +
                                                            • when you need to select the same set of frames as before
                                                            -

                                                            -

                                                            -

                                                            5. Returning to the origin of Clipboard data

                                                            -


                                                            -

                                                            Press Ctrl + B to revert Selection to its state at the moment of the last "Copy to Clipboard" operation.

                                                            -

                                                            When to use:

                                                            -
                                                              -
                                                            • when you need to remember where the Input was copied from
                                                            • +


                                                              +

                                                              5. Returning to the origin of Clipboard data

                                                              +


                                                              +

                                                              Press Ctrl + B to revert Selection to its state at the moment of the last "Copy to Clipboard" operation.

                                                              +

                                                              When to use:

                                                              +
                                                                +
                                                              • when you need to remember where the Input was copied from
                                                              -


                                                              -

                                                              -

                                                              -

                                                              Special

                                                              -


                                                              -

                                                              -

                                                              -

                                                              1. Finding Markers with a given text

                                                              -


                                                              -

                                                              Open the Find Note window, enter the text to search and click Find next or press Enter key to set the Selection cursor to the closest Marker which Note contains the text. The Piano Roll automatically scrolls after the Selection. You can search up or down from the current position of the Selection cursor.

                                                              -

                                                              When to use:

                                                              -
                                                                -
                                                              • when you need to find the segment, knowing some of the exact text it is labeled with
                                                              • +


                                                                +


                                                                +

                                                                Special

                                                                +


                                                                +


                                                                +

                                                                1. Finding Markers with a given text

                                                                +


                                                                +

                                                                Open the Find Note window, enter the text to search and click Find next or press Enter key to set the Selection cursor to the closest Marker which Note contains the text. The Piano Roll automatically scrolls after the Selection. You can search up or down from the current position of the Selection cursor.

                                                                +

                                                                When to use:

                                                                +
                                                                  +
                                                                • when you need to find the segment, knowing some of the exact text it is labeled with
                                                                -

                                                                -

                                                                -

                                                                2. Jumping to the segment with similar description

                                                                -


                                                                -

                                                                Leave the Playback cursor in the current segment and click the Similar or More button to set the Selection cursor to the Marker containing the most relevant Note. The Piano Roll automatically scrolls after the Selection.

                                                                -

                                                                This method is described in the Advanced Features chapter.

                                                                -

                                                                When to use:

                                                                -
                                                                  -
                                                                • when you need to find the segment with a description similar to currently played segment.
                                                                • +


                                                                  +

                                                                  2. Jumping to the segment with similar description

                                                                  +


                                                                  +

                                                                  Leave the Playback cursor in the current segment and click the Similar or More button to set the Selection cursor to the Marker containing the most relevant Note. The Piano Roll automatically scrolls after the Selection.

                                                                  +

                                                                  This method is described in the Advanced Features chapter.

                                                                  +

                                                                  When to use:

                                                                  +
                                                                    +
                                                                  • when you need to find the segment with a description similar to currently played segment.
                                                                  -


                                                                  -


                                                                  -


                                                                  -


                                                                  -


                                                                  +


                                                                  +


                                                                  +


                                                                  +


                                                                  +


                                                                  -

                                                                  Created with the Personal Edition of HelpNDoc: Write EPub books for the iPad

                                                                  -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/NonlinearTASing.html b/web/help/taseditor/NonlinearTASing.html index 909e1b5a..c5911a5c 100644 --- a/web/help/taseditor/NonlinearTASing.html +++ b/web/help/taseditor/NonlinearTASing.html @@ -1,164 +1,352 @@ - - + + + + + - 4.2. Nonlinear TASing - - - - - - - - - - + + + + + + + + 4.2. Nonlinear TASing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      4.2. Nonlinear TASing

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      4.2. Nonlinear TASing

      + +
      +

      -

      Nonlinear TASing

      -


      -


      -

      -

      This is the main method when working with Taseditor. At first it may seem rather different from the traditional TASing, however, they are essentially very similar.

      -

      When using this method, the Recording mode should always be off. The "Auto-restore last position" checkbox should be disabled. The "Turbo seek" and "Follow cursor" checkboxes are usually disabled, but may be enabled when necessary.

      -


      -

      General activity:

      -


      -
        -
      1. Scroll the Piano Roll to the beginning of the edited segment, put the Playback cursor here, define the goal. It's also recommended to mark the beginning with a Marker.
      2. -
      3. Suppose there's a mistake in the segment, weigh known factors of optimality and figure out the way to fix the mistake.
      4. -
      5. The mouse cursor navigation to any frame of the current segment is practically instant.
      6. -
      7. Edit the segment with the mouse. You can either change the Input blindly, or move the Playback cursor from time to time in order to check with the game. The steps 3 and 4 are constantly alternating until you consider the editing complete.
      8. -
      9. Detect the end of the segment by putting the Playback cursor at the target event.
      10. -
      11. [optional step] Save the finished approach to any free Bookmark, e.g. to slot 8 or 7.
      12. -
      13. If this isn't the first approach to the segment, compare the new result to the best old result, using the optimality criterion. If the new approach is better (or it's the first approach), save the result to the Bookmark 9. The slot 9 will be used for keeping the best result of polishing the segment.
      14. -
      15. If you still want to try different approaches, return to step 2, until you run out of ideas.
      16. -
      17. [optional step] If you need more ideas, you can get some information from the past or the future by moving the Playback cursor to different segments of the movie or unpausing the emulator. When necessary, you can quickly draw a rough Input for watching the upcoming events of the game.
      18. -
      19. When there's no more ideas, restore the best approach from the History Log or the Bookmark 9 into the current movie and proceed to the next segment.
      20. +

        Nonlinear TASing

        +


        +


        +

        +

        This is the main method when working with Taseditor. At first it may seem rather different from the traditional TASing, however, they are essentially very similar.

        +

        When using this method, the Recording mode should always be off. The "Auto-restore last position" checkbox should be disabled. The "Turbo seek" and "Follow cursor" checkboxes are usually disabled, but may be enabled when necessary.

        +


        +

        General activity:

        +


        +
          +
        1. Scroll the Piano Roll to the beginning of the edited segment, put the Playback cursor here, define the goal. It's also recommended to mark the beginning with a Marker.
        2. +
        3. Suppose there's a mistake in the segment, weigh known factors of optimality and figure out the way to fix the mistake.
        4. +
        5. The mouse cursor navigation to any frame of the current segment is practically instant.
        6. +
        7. Edit the segment with the mouse. You can either change the Input blindly, or move the Playback cursor from time to time in order to check with the game. The steps 3 and 4 are constantly alternating until you consider the editing complete.
        8. +
        9. Detect the end of the segment by putting the Playback cursor at the target event.
        10. +
        11. [optional step] Save the finished approach to any free Bookmark, e.g. to slot 8 or 7.
        12. +
        13. If this isn't the first approach to the segment, compare the new result to the best old result, using the optimality criterion. If the new approach is better (or it's the first approach), save the result to the Bookmark 9. The slot 9 will be used for keeping the best result of polishing the segment.
        14. +
        15. If you still want to try different approaches, return to step 2, until you run out of ideas.
        16. +
        17. [optional step] If you need more ideas, you can get some information from the past or the future by moving the Playback cursor to different segments of the movie or unpausing the emulator. When necessary, you can quickly draw a rough Input for watching the upcoming events of the game.
        18. +
        19. When there's no more ideas, restore the best approach from the History Log or the Bookmark 9 into the current movie and proceed to the next segment.
        -


        -
        -


        -

        Since all created approaches to playing the segment are automatically saved in the History Log, you could follow the temptation to rely on the Log and not save the approaches to Bookmarks (steps 6 and 7), instead just reach the target event once and then experiment with this Input, gradually improving it (and simply undoing all the changes that are for the worse). Such perfunctory way of TASing is technically possible, but not recommended, because it doesn't let you think far outside the terms of the first approach (because you subconsciously fear to lose the old best approach by leaving it too far away).

        -

        Even if the outcome of the latest modification of the Input made the game behave worse, you should not immediately forget it and revert to the previous state of the movie, better try to examine the cause of the worsening and continue the modification to turn it into an improvement. And in order to never be afraid to lose the previous successful playthrough in the depths of the History Log, you should do exactly like they do in the traditional TASing – allot a special slot for storing the best result and set this Bookmark to the end of the segment every time you improve the result.

        -

        And you can do the same with those promising approaches that are somewhat better, but somewhat worse than the current best result. When you're saving all alternative approaches to separate Bookmarks, you can safely remove their Input from the working movie or change it beyond recognition, because you can return to any of them with a single key press, and no need to search within the History Log.

        -


        -

        Unlike the traditional TASing method, here you may lose sight of dividing the movie into logical segments, because now you don't have to mark the beginning and the end of the current segment with Bookmarks. However, it's still recommended to keep an order and mark the beginning of every important segment with Markers, in order to limit the number of optimality factors.

        -

        The beginning and the end of a segment are usually associated with certain events of the game, and not with a soulless frame number. But since the starting event of the segment is not affected by modifying the Input of the segment, this event will always occur at the same frame, so you can lock the frame with a Marker.

        -

        The ending event of the segment may occur in various points of time, depending on the Input in the segment. So if you mark the end with a Marker, you will need to move the Marker up or down every time you change the target event by modifying the Input. Often it's impractical to spend time on dragging Markers, so instead of the trailing Marker you can use the aforementioned Bookmark which stores the best approach and its icon serves as a mark of the end of current segment.

        -

        -As for simple segments, you can polish them without marking the ending frame at all, by simply relying on your own memory and on the green arrow provided by Taseditor. With this green arrow the Taseditor hints you the frame where you've stopped watching the segment the last time (before you started modifying the Input of the segment). Usually this is the frame where the target event was detected in previous approach. So you may as well replay the updated segment up to the frame and compare the new result with the old one. For example, if the target event is now detected 2 frames above the green arrow, it means you've outran previous result by 2 frames, so the new Input is better (if your criterion is speed). This entire logical chain pops in your mind once you glance at the Piano Roll after watching the outcome of the recent Input modification.

        -


        -

        The process of polishing the Input in the nonlinear method is a constant alternation of editing and watching the segment. You analyze the situation during the watching and right after stopping the watching.

        -

        Possible ways to watch the outcome of Input:

        -
          -
        • unpause the emulator by pressing the Pause hotkey or the middle mouse button. After the segment ends, you have to pause emulator manually (and no problem if you stop it a bit later, since you can always rewind up)
        • -
        • start seeking to the green arrow by pressing the Restore Playback hotkey or the middle mouse button (when the green arrow is outside the Greenzone).
        • -
        • start seeking to the nearest Marker by holding Shift and pressing the middle mouse button
        • -
        • start seeking to the Selection cursor by holding Ctrl and pressing the middle mouse button, granted that the Selection cursor is below the Playback cursor
        • -
        • rewatch the segment from the Selection cursor position to the Playback cursor position by by holding Ctrl and pressing the middle mouse button, granted that the Selection cursor is above the Playback cursor
        • -
        • just drag the Playback cursor manually, using the mouse cursor
        • -
        • move the Playback cursor by holding the right mouse button and rolling the mouse wheel
        • -
        • shift the Playback cursor frame-by-frame using Frame Rewind and Frame Advance hotkeys or < and > buttons or Shift + Up и Shift + Down keys
        • -
        • and there are other ways of navigation with the Playback cursor.
        • +


          +
          +


          +

          Since all created approaches to playing the segment are automatically saved in the History Log, you could follow the temptation to rely on the Log and not save the approaches to Bookmarks (steps 6 and 7), instead just reach the target event once and then experiment with this Input, gradually improving it (and simply undoing all the changes that are for the worse). Such perfunctory way of TASing is technically possible, but not recommended, because it doesn't let you think far outside the terms of the first approach (because you subconsciously fear to lose the old best approach by leaving it too far away).

          +

          Even if the outcome of the latest modification of the Input made the game behave worse, you should not immediately forget it and revert to the previous state of the movie, better try to examine the cause of the worsening and continue the modification to turn it into an improvement. And in order to never be afraid to lose the previous successful playthrough in the depths of the History Log, you should do exactly like they do in the traditional TASing – allot a special slot for storing the best result and set this Bookmark to the end of the segment every time you improve the result.

          +

          And you can do the same with those promising approaches that are somewhat better, but somewhat worse than the current best result. When you're saving all alternative approaches to separate Bookmarks, you can safely remove their Input from the working movie or change it beyond recognition, because you can return to any of them with a single key press, and no need to search within the History Log.

          +


          +

          Unlike the traditional TASing method, here you may lose sight of dividing the movie into logical segments, because now you don't have to mark the beginning and the end of the current segment with Bookmarks. However, it's still recommended to keep an order and mark the beginning of every important segment with Markers, in order to limit the number of optimality factors.

          +

          The beginning and the end of a segment are usually associated with certain events of the game, and not with a soulless frame number. But since the starting event of the segment is not affected by modifying the Input of the segment, this event will always occur at the same frame, so you can lock the frame with a Marker.

          +

          The ending event of the segment may occur in various points of time, depending on the Input in the segment. So if you mark the end with a Marker, you will need to move the Marker up or down every time you change the target event by modifying the Input. Often it's impractical to spend time on dragging Markers, so instead of the trailing Marker you can use the aforementioned Bookmark which stores the best approach and its icon serves as a mark of the end of current segment.

          +

          As for simple segments, you can polish them without marking the ending frame at all, by simply relying on your own memory and on the green arrow provided by Taseditor. With this green arrow the Taseditor hints you the frame where you've stopped watching the segment the last time (before you started modifying the Input of the segment). Usually this is the frame where the target event was detected in previous approach. So you may as well replay the updated segment up to the frame and compare the new result with the old one. For example, if the target event is now detected 2 frames above the green arrow, it means you've outran previous result by 2 frames, so the new Input is better (if your criterion is speed). This entire logical chain pops in your mind once you glance at the Piano Roll after watching the outcome of the recent Input modification.

          +


          +

          The process of polishing the Input in the nonlinear method is a constant alternation of editing and watching the segment. You analyze the situation during the watching and right after stopping the watching.

          +

          Possible ways to watch the outcome of Input:

          +
            +
          • unpause the emulator by pressing the Pause hotkey or the middle mouse button. After the segment ends, you have to pause emulator manually (and no problem if you stop it a bit later, since you can always rewind up)
          • +
          • start seeking to the green arrow by pressing the Restore Playback hotkey or the middle mouse button (when the green arrow is outside the Greenzone).
          • +
          • start seeking to the nearest Marker by holding Shift and pressing the middle mouse button
          • +
          • start seeking to the Selection cursor by holding Ctrl and pressing the middle mouse button, granted that the Selection cursor is below the Playback cursor
          • +
          • rewatch the segment from the Selection cursor position to the Playback cursor position by by holding Ctrl and pressing the middle mouse button, granted that the Selection cursor is above the Playback cursor
          • +
          • just drag the Playback cursor manually, using the mouse cursor
          • +
          • move the Playback cursor by holding the right mouse button and rolling the mouse wheel
          • +
          • shift the Playback cursor frame-by-frame using Frame Rewind and Frame Advance hotkeys or < and > buttons or Shift + Up и Shift + Down keys
          • +
          • and there are other ways of navigation with the Playback cursor.
          -


          -

          Most often you are going to either click the middle mouse button or move the Playback cursor by scrolling the mouse wheel. Don't attach yourself to a single one of the ways, learn to use them depending on the situation.

          -

          The ratio between the time spent on editing and on watching depends on the complexity of the current segment and on the volume of your knowledge about the game. The more you TAS a single game, the better you are aware of its regularities. So near the end of your project you'll be able to foresee the outcome of your Input modifications before even attempting to edit them in. Then you'll only need to watch the segment in order to confirm your guess.

          -

          In some cases you can judge about the optimality of an Input by seeing its interim results and not even watching the segment to the end. For example, if the character bumps into a wall and nullifies his speed in the middle of the segment, you can immediately guess that he is going to reach the target event later than previous time. So sometimes you want to only watch a few frames and continue the editing. However, such a hurry may lead you to reject a solution that is suboptimal at first glance but has a potential to be very successful in another segment. For example, after bumping the wall Mario may accidentally enter inside and go through it. That's why it's recommended to never hurry when TASing, and to watch the current segment to the end, where you can be sure the optimality criterion won't let you down.

          -

          Technically you can watch and edit the Input simultaneously. When the "Follow cursor" checkbox is disabled, the Piano Roll stays still, while the movie is played, so you can draw buttonpresses right when they are executed (replayed). For example, when Mario jumps over an obstacle, try to change the height of the jump by drawing and erasing the A button presses without pausing the emulation. You can slow the emulation down by the - and = hotkeys, in order to have more time for clicking while watching.

          -

          But when you need to have enough time not just for clicking, but also for thinking, better pause the emulator and TAS properly.

          -

          -

          -

          The emulation speed can be both decreased and increased. Before Taseditor, speeding up the emulation was used only for quick replay of the finished part of the movie. But now the turbo emulation also serves as an original way of TASing. With an extremely fast emulation you can feel the interconnection between a buttonpress and its distant outcome.

          -

          -

          -A good example would be the process of luck manipulation.

          -

          Normally, when shooting you can see the connection between pressing the B button and a bullet appearing on screen at the next frame. Applying this association (B = shot) to an in-game situation makes you think "the later I press B, the later the bullet will appear".

          -

          But with turbo-seeking you effectively skip all irrelevant steps of the movie (shooting, bullet flying, collision, enemy death, etc), so right after making the B buttonpress you immediately see which item was dropped by the enemy. This new association (B = possibility of a bonus item) makes you think about this in-game situation more like "the type of the item drop depends on when I press B".

          -

          This way turbo allows to automatically filter useless information that is produced by the game in the middle of the segment, and only consume the necessary data that appears at the end of the segment.

          -

          Here's how you do it:

          -
            -
          • Switch on the "Turbo seek" checkbox. Switch off the "Follow cursor".
          • -
          • Set a trial buttonpress of the B at the beginning of the segment where you can shoot the enemy.
          • -
          • Watch how the bullet hits the enemy and leave the Playback cursor at the frame where the item is supposedly laying on the ground for a second or two. That will be the end of current segment.
          • -
          • So we assume that the first try didn't bring you the needed item, but you know that killing the enemy a bit later may change the outcome. Move the B buttonpress forward one frame (just insert a blank frame before the old position of the buttonpress).
          • -
          • This action makes Taseditor rewind the game back, and on FCEUX screen you can see the moment before shooting.
          • -
          • Press the middle mouse button or Spacebar (the key assigned to the Restore Playback hotkey). The game events will replay like a flash, and you'll almost immediately see which item the enemy drops now.
          • -
          • If the result is not satisfying, press Ctrl + Shift + Insert again, thus inserting another frame before the existing B buttonpress. The shot is delayed by one more frame. Restore Playback again to see the new result.
          • -
          • Continue until you find the frame where shooting the enemy brings you the needed item. This way you can test a hundred of options within a minute, by simply pressing the hotkeys and only watching the FCEUX screen.
          • +


            +

            Most often you are going to either click the middle mouse button or move the Playback cursor by scrolling the mouse wheel. Don't attach yourself to a single one of the ways, learn to use them depending on the situation.

            +

            The ratio between the time spent on editing and on watching depends on the complexity of the current segment and on the volume of your knowledge about the game. The more you TAS a single game, the better you are aware of its regularities. So near the end of your project you'll be able to foresee the outcome of your Input modifications before even attempting to edit them in. Then you'll only need to watch the segment in order to confirm your guess.

            +

            In some cases you can judge about the optimality of an Input by seeing its interim results and not even watching the segment to the end. For example, if the character bumps into a wall and nullifies his speed in the middle of the segment, you can immediately guess that he is going to reach the target event later than previous time. So sometimes you want to only watch a few frames and continue the editing. However, such a hurry may lead you to reject a solution that is suboptimal at first glance but has a potential to be very successful in another segment. For example, after bumping the wall Mario may accidentally enter inside and go through it. That's why it's recommended to never hurry when TASing, and to watch the current segment to the end, where you can be sure the optimality criterion won't let you down.

            +

            Technically you can watch and edit the Input simultaneously. When the "Follow cursor" checkbox is disabled, the Piano Roll stays still, while the movie is played, so you can draw buttonpresses right when they are executed (replayed). For example, when Mario jumps over an obstacle, try to change the height of the jump by drawing and erasing the A button presses without pausing the emulation. You can slow the emulation down by the - and = hotkeys, in order to have more time for clicking while watching.

            +

            But when you need to have enough time not just for clicking, but also for thinking, better pause the emulator and TAS properly.

            +


            +

            The emulation speed can be both decreased and increased. Before Taseditor, speeding up the emulation was used only for quick replay of the finished part of the movie. But now the turbo emulation also serves as an original way of TASing. With an extremely fast emulation you can feel the interconnection between a buttonpress and its distant outcome.

            +

            +

            A good example would be the process of luck manipulation.

            +

            Normally, when shooting you can see the connection between pressing the B button and a bullet appearing on screen at the next frame. Applying this association (B = shot) to an in-game situation makes you think "the later I press B, the later the bullet will appear".

            +

            But with turbo-seeking you effectively skip all irrelevant steps of the movie (shooting, bullet flying, collision, enemy death, etc), so right after making the B buttonpress you immediately see which item was dropped by the enemy. This new association (B = possibility of a bonus item) makes you think about this in-game situation more like "the type of the item drop depends on when I press B".

            +

            This way turbo allows to automatically filter useless information that is produced by the game in the middle of the segment, and only consume the necessary data that appears at the end of the segment.

            +

            Here's how you do it:

            +
              +
            • Switch on the "Turbo seek" checkbox. Switch off the "Follow cursor".
            • +
            • Set a trial buttonpress of the B at the beginning of the segment where you can shoot the enemy.
            • +
            • Watch how the bullet hits the enemy and leave the Playback cursor at the frame where the item is supposedly laying on the ground for a second or two. That will be the end of current segment.
            • +
            • So we assume that the first try didn't bring you the needed item, but you know that killing the enemy a bit later may change the outcome. Move the B buttonpress forward one frame (just insert a blank frame before the old position of the buttonpress).
            • +
            • This action makes Taseditor rewind the game back, and on FCEUX screen you can see the moment before shooting.
            • +
            • Press the middle mouse button or Spacebar (the key assigned to the Restore Playback hotkey). The game events will replay like a flash, and you'll almost immediately see which item the enemy drops now.
            • +
            • If the result is not satisfying, press Ctrl + Shift + Insert again, thus inserting another frame before the existing B buttonpress. The shot is delayed by one more frame. Restore Playback again to see the new result.
            • +
            • Continue until you find the frame where shooting the enemy brings you the needed item. This way you can test a hundred of options within a minute, by simply pressing the hotkeys and only watching the FCEUX screen.
            -


            -
            -


            -

            Pros of the method:

            -

            + Instant navigation.

            -

            + Possibility to skip useless scenes.

            -

            + Detachment from the game flow increases the objectivity of analysis.

            -


            -

            Cons of the method:

            -

            Lack of the feedback inherent to normal game-player interaction.

            -

            Emphasis on the mouse controls.

            -


            -

            When the method is recommended to use: most of time. Combine this method with the next method in order to construct the full picture of the in-game possibilities.

            -


            -

            The next method fixes the main disadvantage of this method.

            -


            -


            -


            -


            -


            +


            +
            +


            +

            Pros of the method:

            +

            + Instant navigation.

            +

            + Possibility to skip useless scenes.

            +

            + Detachment from the game flow increases the objectivity of analysis.

            +


            +

            Cons of the method:

            +

            Lack of the feedback inherent to normal game-player interaction.

            +

            Emphasis on the mouse controls.

            +


            +

            When the method is recommended to use: most of time. Combine this method with the next method in order to construct the full picture of the in-game possibilities.

            +


            +

            The next method fixes the main disadvantage of this method.

            +


            +


            +


            +


            +


            -

            Created with the Personal Edition of HelpNDoc: Easily create EBooks

            -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/Operations.html b/web/help/taseditor/Operations.html index 8d71033e..67343e91 100644 --- a/web/help/taseditor/Operations.html +++ b/web/help/taseditor/Operations.html @@ -1,687 +1,887 @@ - - + + + + + - Operations - - - - - - - - - - + + + + + + + + Operations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Operations

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Operations

      + +
      +

      -

      Operations

      +

      Operations



      -

      All modifications of the movie are registered in History Log. Every record of the Log contains the time when the modification was done and the keyframe (or starting and ending frames of the section) to which the modification was applied.

      -

      Here you can find the list of all possible types of History Log records and corresponding operations with the movie.

      -


      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

      All modifications of the movie are registered in History Log. Every record of the Log contains the time when the modification was done and the keyframe (or starting and ending frames of the section) to which the modification was applied.

      +

      Here you can find the list of all possible types of History Log records and corresponding operations with the movie.

      +


      +
      +

      Input change

      -

      Markers change

      -

      Other

      -

      Set

      -

      Marker Set

      -

      Initialization

      -

      Unset

      -

      Marker Remove

      -

      Undefined

      -

      Pattern

      -

      Marker Pattern

      -


      -

      Clear

      -


      -

      Cut

      -

      Paste

      -

      PasteInsert

      -

      Clone

      -

      Insert

      -

      Insert#

      -

      Delete

      -

      Truncate

      -

      Record

      -


      -

      Import

      -

      Branch

      -

      Bookmark

      -


      -

      Marker Branch

      -


      -

      Marker Rename

      -

      Marker Drag

      -

      Marker Swap

      -

      Marker Shift

      -

      LUA Marker Set

      -

      LUA Marker Remove

      -

      LUA Marker Rename

      -

      LUA Change

      -
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +

      Input change

      +
      +

      Markers change

      +
      +

      Other

      +
      +

      Set

      +
      +

      Marker Set

      +
      +

      Initialization

      +
      +

      Unset

      +
      +

      Marker Remove

      +
      +

      Undefined

      +
      +

      Pattern

      +
      +

      Marker Pattern

      +
      +


      +
      +

      Clear

      +
      +


      +
      +

      Cut

      +
      +

      Paste

      +
      +

      PasteInsert

      +
      +

      Clone

      +
      +

      Insert

      +
      +

      Insert#

      +
      +

      Delete

      +
      +

      Truncate

      +
      +

      Record

      +
      +


      +
      +

      Import

      +
      +

      Branch

      +
      +

      Bookmark

      +
      +


      +
      +

      Marker Branch

      +
      +


      +
      +

      Marker Rename

      +
      +

      Marker Drag

      +
      +

      Marker Swap

      +
      +

      Marker Shift

      +
      +

      LUA Marker Set

      +
      +

      LUA Marker Remove

      +
      +

      LUA Marker Rename

      +
      +

      LUA Change

      +
      -


      -
      -

      -

      -

      Initialization

      -

      Category: other

      -

      The record is created automatically when a new History Log is created.

      -

      Examples:

      -
        -
      • when creating a new project
      • -
      • when loading a compactly saved project that has no History Log
      • +


        +
        +


        +

        Initialization

        +

        Category: other

        +

        The record is created automatically when a new History Log is created.

        +

        Examples:

        +
          +
        • when creating a new project
        • +
        • when loading a compactly saved project that has no History Log
        -

        20:24:53 Initialization

        -

        Used: very rarely

        -

        Greenzone is truncated after zeroth frame.

        -


        -

        -

        -

        Undefined

        -

        Category: other

        -

        Undefined modification. The record should not appear in TAS Editor 1.0.

        -

        Used: never

        -


        -

        -

        -

        Set

        -

        Category: Input change

        -

        The record is created when one or more buttonpresses appear in one or several frames.

        -

        Examples:

        -
          -
        • click on an empty Input cell of the Piano Roll
        • -
        • draw a new stroke by dragging the mouse after clicking on an empty Input cell
        • -
        • Shift + click on an empty Input cell
        • -
        • select some frames and then click on a button symbol in the Header of the Piano Roll
        • -
        • select some frames and then press a key assigned to a virtual gamepad button
        • +

          20:24:53 Initialization

          +

          Used: very rarely

          +

          Greenzone is truncated after zeroth frame.

          +


          +


          +

          Undefined

          +

          Category: other

          +

          Undefined modification. The record should not appear in TAS Editor 1.0.

          +

          Used: never

          +


          +


          +

          Set

          +

          Category: Input change

          +

          The record is created when one or more buttonpresses appear in one or several frames.

          +

          Examples:

          +
            +
          • click on an empty Input cell of the Piano Roll
          • +
          • draw a new stroke by dragging the mouse after clicking on an empty Input cell
          • +
          • Shift + click on an empty Input cell
          • +
          • select some frames and then click on a button symbol in the Header of the Piano Roll
          • +
          • select some frames and then press a key assigned to a virtual gamepad button
          -

          20:25:18 Set 15-21

          -

          Used: very often

          -

          Greenzone is truncated after the first frame where Input was changed.

          -


          -

          -

          -

          Unset

          -

          Category: Input change

          -

          The record is created when one or more buttonpresses disappear from one or several frames.

          -

          Examples:

          -
            -
          • click on an occupied Input cell of the Piano Roll
          • -
          • erase some Input by dragging the mouse after clicking on an occupied Input cell
          • -
          • Shift + click on an occupied Input cell
          • -
          • select some frames and then click on a button symbol in the Header of the Piano Roll
          • -
          • select some frames and then press a key assigned to a virtual gamepad button
          • +

            20:25:18 Set 15-21

            +

            Used: very often

            +

            Greenzone is truncated after the first frame where Input was changed.

            +


            +


            +

            Unset

            +

            Category: Input change

            +

            The record is created when one or more buttonpresses disappear from one or several frames.

            +

            Examples:

            +
              +
            • click on an occupied Input cell of the Piano Roll
            • +
            • erase some Input by dragging the mouse after clicking on an occupied Input cell
            • +
            • Shift + click on an occupied Input cell
            • +
            • select some frames and then click on a button symbol in the Header of the Piano Roll
            • +
            • select some frames and then press a key assigned to a virtual gamepad button
            -

            20:25:22 Unset 21

            -

            Used: very often

            -

            Greenzone is truncated after the first frame where Input was changed.

            -


            -

            -

            -

            Pattern

            -

            Category: Input change

            -

            The record is created when a sequence of buttonpresses changes to currently chosen pattern.

            -

            The name of the pattern is added to the text of the record.

            -

            Examples:

            -
              -
            • Alt + click on an Input cell of the Piano Roll
            • -
            • Alt + dragging the mouse after clicking on an Input cell
            • -
            • select some frames and then Alt + click on a button symbol in the Header of the Piano Roll
            • -
            • select some frames and then Alt + press a key assigned to a virtual gamepad button
            • +

              20:25:22 Unset 21

              +

              Used: very often

              +

              Greenzone is truncated after the first frame where Input was changed.

              +


              +


              +

              Pattern

              +

              Category: Input change

              +

              The record is created when a sequence of buttonpresses changes to currently chosen pattern.

              +

              The name of the pattern is added to the text of the record.

              +

              Examples:

              +
                +
              • Alt + click on an Input cell of the Piano Roll
              • +
              • Alt + dragging the mouse after clicking on an Input cell
              • +
              • select some frames and then Alt + click on a button symbol in the Header of the Piano Roll
              • +
              • select some frames and then Alt + press a key assigned to a virtual gamepad button
              -

              20:25:40 Pattern 21-30 Alternating (1010...)

              -

              Used: rarely

              -

              Greenzone is truncated after the first frame where Input was changed.

              -


              -

              -

              -

              Clear

              -

              Category: Input change

              -

              The record is created when all buttonpresses disappear from one or several frames.

              -

              Examples:

              -
                -
              • select some frames and then press Delete
              • -
              • select some frames and then choose Edit -> Clear in TAS Editor menu
              • -
              • right-click on a selected frame number and choose Clear in the context menu
              • +

                20:25:40 Pattern 21-30 Alternating (1010...)

                +

                Used: rarely

                +

                Greenzone is truncated after the first frame where Input was changed.

                +


                +


                +

                Clear

                +

                Category: Input change

                +

                The record is created when all buttonpresses disappear from one or several frames.

                +

                Examples:

                +
                  +
                • select some frames and then press Delete
                • +
                • select some frames and then choose Edit -> Clear in TAS Editor menu
                • +
                • right-click on a selected frame number and choose Clear in the context menu
                -

                20:26:51 Clear 15-20

                -

                Used: moderately

                -

                Greenzone is truncated after the first frame where Input was changed.

                -


                -

                -

                -

                Cut

                -

                Category: Input change

                -

                The record is created when all buttonpresses disappear from one or several frames, caused by "Cut" operation.

                -

                This is identical to the Clear operation, except that buttonpresses are copied to the Clipboard before deleting them.

                -

                Note: although you can undo this operation, the Clipboard contents won't revert.

                -

                Examples:

                -
                  -
                • select some frames and then press Ctrl + X
                • -
                • select some frames and then choose Edit -> Cut in TAS Editor menu
                • +

                  20:26:51 Clear 15-20

                  +

                  Used: moderately

                  +

                  Greenzone is truncated after the first frame where Input was changed.

                  +


                  +


                  +

                  Cut

                  +

                  Category: Input change

                  +

                  The record is created when all buttonpresses disappear from one or several frames, caused by "Cut" operation.

                  +

                  This is identical to the Clear operation, except that buttonpresses are copied to the Clipboard before deleting them.

                  +

                  Note: although you can undo this operation, the Clipboard contents won't revert.

                  +

                  Examples:

                  +
                    +
                  • select some frames and then press Ctrl + X
                  • +
                  • select some frames and then choose Edit -> Cut in TAS Editor menu
                  -

                  20:27:05 Cut 21-23

                  -

                  Used: rarely

                  -

                  Greenzone is truncated after the first frame where Input was changed.

                  -


                  -

                  -

                  -

                  Paste

                  -

                  Category: Input change

                  -

                  The record is created when a Clipboard data is pasted into the movie.

                  -

                  Depending on the "Superimpose" checkbox, the old Input on those frames is either erased or combined with the new Input. The Piano Roll Header briefly flashes symbols of those buttons that were added in the Paste process.

                  -

                  Examples:

                  -
                    -
                  • select some frames and then press Ctrl + V
                  • -
                  • select some frames and then choose Edit -> Paste in TAS Editor menu
                  • +

                    20:27:05 Cut 21-23

                    +

                    Used: rarely

                    +

                    Greenzone is truncated after the first frame where Input was changed.

                    +


                    +


                    +

                    Paste

                    +

                    Category: Input change

                    +

                    The record is created when a Clipboard data is pasted into the movie.

                    +

                    Depending on the "Superimpose" checkbox, the old Input on those frames is either erased or combined with the new Input. The Piano Roll Header briefly flashes symbols of those buttons that were added in the Paste process.

                    +

                    Examples:

                    +
                      +
                    • select some frames and then press Ctrl + V
                    • +
                    • select some frames and then choose Edit -> Paste in TAS Editor menu
                    -

                    20:27:11 Paste 21

                    -

                    Used: moderately/rarely

                    -

                    Greenzone is truncated after the first frame where Input was changed.

                    -


                    -

                    -

                    -

                    PasteInsert

                    -

                    Category: Input change, Markers change

                    -

                    The record is created when a Clipboard data is inserted into the movie.

                    -

                    Old Input and Markers are shifted down to make place for the Input from Clipboard.

                    -

                    Examples:

                    -
                      -
                    • select some frames and then press Ctrl + Shift + V
                    • -
                    • select some frames and then choose Edit -> PasteInsert in TAS Editor menu
                    • +

                      20:27:11 Paste 21

                      +

                      Used: moderately/rarely

                      +

                      Greenzone is truncated after the first frame where Input was changed.

                      +


                      +


                      +

                      PasteInsert

                      +

                      Category: Input change, Markers change

                      +

                      The record is created when a Clipboard data is inserted into the movie.

                      +

                      Old Input and Markers are shifted down to make place for the Input from Clipboard.

                      +

                      Examples:

                      +
                        +
                      • select some frames and then press Ctrl + Shift + V
                      • +
                      • select some frames and then choose Edit -> PasteInsert in TAS Editor menu
                      -

                      20:27:16 PasteInsert 21

                      -

                      Used: rarely

                      -

                      Greenzone is truncated after the first frame where Input or Lag was changed.

                      -


                      -

                      -

                      -

                      Clone

                      -

                      Category: Input change, Markers change

                      -

                      The record is created when copies of one or several frames are inserted into the movie, shifting the following Input and Markers down.

                      -

                      Examples:

                      -
                        -
                      • select some frames and then press Ctrl + Insert
                      • -
                      • select some frames and then choose Edit -> Clone in TAS Editor menu
                      • -
                      • right-click on a selected frame number and choose Clone in the context menu
                      • +

                        20:27:16 PasteInsert 21

                        +

                        Used: rarely

                        +

                        Greenzone is truncated after the first frame where Input or Lag was changed.

                        +


                        +


                        +

                        Clone

                        +

                        Category: Input change, Markers change

                        +

                        The record is created when copies of one or several frames are inserted into the movie, shifting the following Input and Markers down.

                        +

                        Examples:

                        +
                          +
                        • select some frames and then press Ctrl + Insert
                        • +
                        • select some frames and then choose Edit -> Clone in TAS Editor menu
                        • +
                        • right-click on a selected frame number and choose Clone in the context menu
                        -

                        20:27:34 Clone 23

                        -

                        Used: often

                        -

                        Greenzone is truncated after the first frame where Input or Lag was changed.

                        -


                        -

                        -

                        -

                        Insert

                        -

                        Category: Input change, Markers change

                        -

                        The record is created when one or several blank frames are inserted into the movie, shifting the following Input and Markers down.

                        -

                        Examples:

                        -
                          -
                        • select some frames and then press Ctrl + Shift + Insert
                        • -
                        • select some frames and then choose Edit -> Insert in TAS Editor menu
                        • -
                        • right-click on a selected frame number and choose Insert in the context menu
                        • +

                          20:27:34 Clone 23

                          +

                          Used: often

                          +

                          Greenzone is truncated after the first frame where Input or Lag was changed.

                          +


                          +


                          +

                          Insert

                          +

                          Category: Input change, Markers change

                          +

                          The record is created when one or several blank frames are inserted into the movie, shifting the following Input and Markers down.

                          +

                          Examples:

                          +
                            +
                          • select some frames and then press Ctrl + Shift + Insert
                          • +
                          • select some frames and then choose Edit -> Insert in TAS Editor menu
                          • +
                          • right-click on a selected frame number and choose Insert in the context menu
                          -

                          20:25:58 Insert 21

                          -

                          Used: moderately

                          -

                          Greenzone is truncated after the first frame where Input or Lag was changed.

                          -


                          -

                          -

                          -

                          Insert#

                          -

                          Category: Input change, Markers change

                          -

                          The record is created when a specific number of blank frames is inserted into the movie, shifting the following Input and Markers down.

                          -

                          If there's Selection in the Piano Roll, this operation inserts frames before the Selection, otherwise it inserts frames before the Playback cursor.

                          -

                          The number of inserted frames is added to the text of the record.

                          -

                          Examples:

                          -
                            -
                          • press Insert and enter the number of frames to insert
                          • -
                          • choose Edit -> Insert # of Frames in TAS Editor menu
                          • -
                          • right-click on a selected frame number and choose Insert # of Frames in the context menu
                          • +

                            20:25:58 Insert 21

                            +

                            Used: moderately

                            +

                            Greenzone is truncated after the first frame where Input or Lag was changed.

                            +


                            +


                            +

                            Insert#

                            +

                            Category: Input change, Markers change

                            +

                            The record is created when a specific number of blank frames is inserted into the movie, shifting the following Input and Markers down.

                            +

                            If there's Selection in the Piano Roll, this operation inserts frames before the Selection, otherwise it inserts frames before the Playback cursor.

                            +

                            The number of inserted frames is added to the text of the record.

                            +

                            Examples:

                            +
                              +
                            • press Insert and enter the number of frames to insert
                            • +
                            • choose Edit -> Insert # of Frames in TAS Editor menu
                            • +
                            • right-click on a selected frame number and choose Insert # of Frames in the context menu
                            -

                            20:26:09 Insert#4 29

                            -

                            Used: rarely

                            -

                            Greenzone is truncated after the first frame where Input or Lag was changed.

                            -


                            -

                            -

                            -

                            Delete

                            -

                            Category: Input change, Markers change

                            -

                            The record is created when one or several frames are deleted from the movie, shifting the following Input and Markers up.

                            -

                            Examples:

                            -
                              -
                            • select some frames and then press Ctrl + Delete
                            • -
                            • select some frames and then choose Edit -> Delete in TAS Editor menu
                            • -
                            • right-click on a selected frame number and choose Delete in the context menu
                            • +

                              20:26:09 Insert#4 29

                              +

                              Used: rarely

                              +

                              Greenzone is truncated after the first frame where Input or Lag was changed.

                              +


                              +


                              +

                              Delete

                              +

                              Category: Input change, Markers change

                              +

                              The record is created when one or several frames are deleted from the movie, shifting the following Input and Markers up.

                              +

                              Examples:

                              +
                                +
                              • select some frames and then press Ctrl + Delete
                              • +
                              • select some frames and then choose Edit -> Delete in TAS Editor menu
                              • +
                              • right-click on a selected frame number and choose Delete in the context menu
                              -

                              20:26:12 Delete 33

                              -

                              Used: often

                              -

                              Greenzone is truncated after the first frame where Input or Lag was changed.

                              -


                              -

                              -

                              -

                              Truncate

                              -

                              Category: Input change, Markers change

                              -

                              The record is created when the tail of the movie is truncated, deleting all Input (and Markers) starting from either the Selection cursor or the Playback cursor (when there's no Selection).

                              -

                              Examples:

                              -
                                -
                              • choose Edit -> Truncate movie in TAS Editor menu
                              • -
                              • right-click on a selected frame number and choose Truncate movie in the context menu
                              • +

                                20:26:12 Delete 33

                                +

                                Used: often

                                +

                                Greenzone is truncated after the first frame where Input or Lag was changed.

                                +


                                +


                                +

                                Truncate

                                +

                                Category: Input change, Markers change

                                +

                                The record is created when the tail of the movie is truncated, deleting all Input (and Markers) starting from either the Selection cursor or the Playback cursor (when there's no Selection).

                                +

                                Examples:

                                +
                                  +
                                • choose Edit -> Truncate movie in TAS Editor menu
                                • +
                                • right-click on a selected frame number and choose Truncate movie in the context menu
                                -

                                20:26:28 Truncate 42

                                -

                                Used: very rarely

                                -

                                Greenzone is truncated after the frame of movie truncation.

                                -


                                -

                                -

                                -

                                Record

                                -

                                Category: Input change

                                -

                                The record is created when the emulator is recording Input using gamepads.

                                -

                                The new Input appears at the Playback cursor frame. Depending on the "Superimpose" checkbox, the old Input of the frame is either overwritten or combined with the new Input. The Piano Roll Header briefly flashes symbols of those buttons that were added in the Recording process.

                                -

                                IDs of gamepads whose Input was changed are added to the text of the record.

                                -

                                Examples:

                                -
                                  -
                                • switch Recording mode on, unpause the emulator and press any keys assigned to buttons of gamepads
                                • -
                                • when emulator is paused, switch Recording mode on, hold any keys assigned to buttons of virtual pads and press Frame Advance
                                • +

                                  20:26:28 Truncate 42

                                  +

                                  Used: very rarely

                                  +

                                  Greenzone is truncated after the frame of movie truncation.

                                  +


                                  +


                                  +

                                  Record

                                  +

                                  Category: Input change

                                  +

                                  The record is created when the emulator is recording Input using gamepads.

                                  +

                                  The new Input appears at the Playback cursor frame. Depending on the "Superimpose" checkbox, the old Input of the frame is either overwritten or combined with the new Input. The Piano Roll Header briefly flashes symbols of those buttons that were added in the Recording process.

                                  +

                                  IDs of gamepads whose Input was changed are added to the text of the record.

                                  +

                                  Examples:

                                  +
                                    +
                                  • switch Recording mode on, unpause the emulator and press any keys assigned to buttons of gamepads
                                  • +
                                  • when emulator is paused, switch Recording mode on, hold any keys assigned to buttons of virtual pads and press Frame Advance
                                  -

                                  20:28:01 Record(1P) 18-24

                                  -

                                  Used: moderately

                                  -

                                  Greenzone is truncated after the Playback cursor position.

                                  -


                                  -

                                  -

                                  -

                                  Import

                                  -

                                  Category: Input change

                                  -

                                  The record is created when an Input from another FM2/FM3 movie is imported into the current project.

                                  -

                                  Current movie Input is substituted by the Input of imported file. Markers are not changed.

                                  -

                                  The filename of the Input source is added to the text of the record.

                                  -

                                  Examples:

                                  -
                                    -
                                  • choose File -> Import Input in TAS Editor menu and open the file which should be the source of Input
                                  • +

                                    20:28:01 Record(1P) 18-24

                                    +

                                    Used: moderately

                                    +

                                    Greenzone is truncated after the Playback cursor position.

                                    +


                                    +


                                    +

                                    Import

                                    +

                                    Category: Input change

                                    +

                                    The record is created when an Input from another FM2/FM3 movie is imported into the current project.

                                    +

                                    Current movie Input is substituted by the Input of imported file. Markers are not changed.

                                    +

                                    The filename of the Input source is added to the text of the record. 

                                    +

                                    Examples:

                                    +
                                      +
                                    • choose File -> Import Input in TAS Editor menu and open the file which should be the source of Input
                                    -

                                    20:28:53 Import Battletoads-WIP1.fm2

                                    -

                                    Used: very rarely

                                    -

                                    Greenzone is truncated after the first frame where Input was changed.

                                    -


                                    -

                                    -

                                    -

                                    Bookmark0

                                    -

                                    Bookmark1

                                    -

                                    Bookmark2

                                    -

                                    Bookmark3

                                    -

                                    Bookmark4

                                    -

                                    Bookmark5

                                    -

                                    Bookmark6

                                    -

                                    Bookmark7

                                    -

                                    Bookmark8

                                    -

                                    Bookmark9

                                    -

                                    Category: other

                                    -

                                    The record is created when the data of a Bookmark slot is changed.

                                    -

                                    Note: re-saving a Bookmark into the same slot only works when the new Bookmark data differs from the data stored in the slot, e.g. when the Bookmark is placed to another frame or when the current movie Input differs from the Input stored in the slot.

                                    -

                                    When a Bookmark is successfully saved, its Branch becomes "the current branch of the movie", and the emulator shows the message "Branch # saved."

                                    -

                                    Examples:

                                    -
                                      -
                                    • press a "Save state" hotkey: Shift + key in the row from F1 to F10
                                    • -
                                    • right-click anywhere inside the Bookmarks List
                                    • -
                                    • right-click on a Bookmark icon in the Branches Tree
                                    • +

                                      20:28:53 Import Battletoads-WIP1.fm2

                                      +

                                      Used: very rarely

                                      +

                                      Greenzone is truncated after the first frame where Input was changed.

                                      +


                                      +


                                      +

                                      Bookmark0

                                      +

                                      Bookmark1

                                      +

                                      Bookmark2

                                      +

                                      Bookmark3

                                      +

                                      Bookmark4

                                      +

                                      Bookmark5

                                      +

                                      Bookmark6

                                      +

                                      Bookmark7

                                      +

                                      Bookmark8

                                      +

                                      Bookmark9

                                      +

                                      Category: other

                                      +

                                      The record is created when the data of a Bookmark slot is changed.

                                      +

                                      Note: re-saving a Bookmark into the same slot only works when the new Bookmark data differs from the data stored in the slot, e.g. when the Bookmark is placed to another frame or when the current movie Input differs from the Input stored in the slot.

                                      +

                                      When a Bookmark is successfully saved, its Branch becomes "the current branch of the movie", and the emulator shows the message "Branch # saved."

                                      +

                                      Examples:

                                      +
                                        +
                                      • press a "Save state" hotkey: Shift + key in the row from F1 to F10
                                      • +
                                      • right-click anywhere inside the Bookmarks List
                                      • +
                                      • right-click on a Bookmark icon in the Branches Tree
                                      -

                                      20:28:53 Bookmark1 10

                                      -

                                      Used: often

                                      -

                                      Greenzone is not truncated.

                                      -


                                      -

                                      -

                                      -

                                      Branch0 to

                                      -

                                      Branch1 to

                                      -

                                      Branch2 to

                                      -

                                      Branch3 to

                                      -

                                      Branch4 to

                                      -

                                      Branch5 to

                                      -

                                      Branch6 to

                                      -

                                      Branch7 to

                                      -

                                      Branch8 to

                                      -

                                      Branch9 to

                                      -

                                      Category: Input change, Markers change

                                      -

                                      The record is created when the current movie is substituted with the data of a Bookmark slot. Both Input and Markers are substituted.

                                      -

                                      The time of the Bookmark creation is added to the text of the record, because the movie is actually reverted to its own state at that time.

                                      -

                                      When a Bookmark is successfully loaded, its Branch becomes "the current branch of the movie", and the emulator shows the message "Branch # loaded."

                                      -

                                      Examples:

                                      -
                                        -
                                      • press a "Load state" hotkey: Shift + key in the row from F1 to F10
                                      • -
                                      • click on the right half of the Bookmarks List
                                      • -
                                      • double-click on a Bookmark icon in the Branches Tree
                                      • +

                                        20:28:53 Bookmark1 10

                                        +

                                        Used: often

                                        +

                                        Greenzone is not truncated.

                                        +


                                        +


                                        +

                                        Branch0 to

                                        +

                                        Branch1 to

                                        +

                                        Branch2 to

                                        +

                                        Branch3 to

                                        +

                                        Branch4 to

                                        +

                                        Branch5 to

                                        +

                                        Branch6 to

                                        +

                                        Branch7 to

                                        +

                                        Branch8 to

                                        +

                                        Branch9 to

                                        +

                                        Category: Input change, Markers change

                                        +

                                        The record is created when the current movie is substituted with the data of a Bookmark slot. Both Input and Markers are substituted.

                                        +

                                        The time of the Bookmark creation is added to the text of the record, because the movie is actually reverted to its own state at that time.

                                        +

                                        When a Bookmark is successfully loaded, its Branch becomes "the current branch of the movie", and the emulator shows the message "Branch # loaded."

                                        +

                                        Examples:

                                        +
                                          +
                                        • press a "Load state" hotkey: Shift + key in the row from F1 to F10
                                        • +
                                        • click on the right half of the Bookmarks List
                                        • +
                                        • double-click on a Bookmark icon in the Branches Tree
                                        -

                                        20:29:02 Branch1 to 20:28:15

                                        -

                                        Used: moderately

                                        -

                                        Greenzone is truncated after the first frame where Input or Lag was changed.

                                        -


                                        -

                                        -

                                        -

                                        Marker Branch0 to

                                        -

                                        Marker Branch1 to

                                        -

                                        Marker Branch2 to

                                        -

                                        Marker Branch3 to

                                        -

                                        Marker Branch4 to

                                        -

                                        Marker Branch5 to

                                        -

                                        Marker Branch6 to

                                        -

                                        Marker Branch7 to

                                        -

                                        Marker Branch8 to

                                        -

                                        Marker Branch9 to

                                        -

                                        Category: Markers change

                                        -

                                        The record is created when current movie is substituted with the data of a Bookmark slot, but the new Input was identical to the old Input, and only Markers were different.

                                        -

                                        Examples:

                                        -
                                          -
                                        • press a "Load state" hotkey: Shift + key in the row from F1 to F10
                                        • -
                                        • click on the right half of the Bookmarks List
                                        • -
                                        • double-click on the a Bookmark icon in the Branches Tree
                                        • +

                                          20:29:02 Branch1 to 20:28:15

                                          +

                                          Used: moderately

                                          +

                                          Greenzone is truncated after the first frame where Input or Lag was changed.

                                          +


                                          +


                                          +

                                          Marker Branch0 to

                                          +

                                          Marker Branch1 to

                                          +

                                          Marker Branch2 to

                                          +

                                          Marker Branch3 to

                                          +

                                          Marker Branch4 to

                                          +

                                          Marker Branch5 to

                                          +

                                          Marker Branch6 to

                                          +

                                          Marker Branch7 to

                                          +

                                          Marker Branch8 to

                                          +

                                          Marker Branch9 to

                                          +

                                          Category: Markers change

                                          +

                                          The record is created when current movie is substituted with the data of a Bookmark slot, but the new Input was identical to the old Input, and only Markers were different.

                                          +

                                          Examples:

                                          +
                                            +
                                          • press a "Load state" hotkey: Shift + key in the row from F1 to F10
                                          • +
                                          • click on the right half of the Bookmarks List
                                          • +
                                          • double-click on the a Bookmark icon in the Branches Tree
                                          -

                                          20:29:33 Marker Branch1 to 20:28:15

                                          -

                                          Used: very rarely

                                          -

                                          Greenzone is not truncated.

                                          -


                                          -

                                          -

                                          -

                                          Marker Set

                                          -

                                          Category: Markers change

                                          -

                                          The record is created when a Marker appears on one or several frames.

                                          -

                                          Examples:

                                          -
                                            -
                                          • double-click on a non-marked frame number in the Piano Roll
                                          • -
                                          • select some frames and then click on the "Frame#" in the Header of the Piano Roll
                                          • -
                                          • right-click on a selected frame number and choose Set Markers in the context menu
                                          • +

                                            20:29:33 Marker Branch1 to 20:28:15

                                            +

                                            Used: very rarely

                                            +

                                            Greenzone is not truncated.

                                            +


                                            +


                                            +

                                            Marker Set

                                            +

                                            Category: Markers change

                                            +

                                            The record is created when a Marker appears on one or several frames.

                                            +

                                            Examples:

                                            +
                                              +
                                            • double-click on a non-marked frame number in the Piano Roll
                                            • +
                                            • select some frames and then click on the "Frame#" in the Header of the Piano Roll
                                            • +
                                            • right-click on a selected frame number and choose Set Markers in the context menu
                                            -

                                            20:29:47 Marker Set 15-18

                                            -

                                            Used: often

                                            -

                                            Greenzone is not truncated.

                                            -


                                            -

                                            -

                                            -

                                            Marker Remove

                                            -

                                            Category: Markers change

                                            -

                                            The record is created when Markers disappear from one or several frames.

                                            -

                                            Examples:

                                            -
                                              -
                                            • double-click on a marked frame number in the Piano Roll, drag the Marker outside the Piano Roll and release it
                                            • -
                                            • select some frames and then click on the "Frame#" in the Header of the Piano Roll
                                            • -
                                            • right-click on a selected frame number and choose Remove Markers in the context menu
                                            • +

                                              20:29:47 Marker Set 15-18

                                              +

                                              Used: often

                                              +

                                              Greenzone is not truncated.

                                              +


                                              +


                                              +

                                              Marker Remove

                                              +

                                              Category: Markers change

                                              +

                                              The record is created when Markers disappear from one or several frames.

                                              +

                                              Examples:

                                              +
                                                +
                                              • double-click on a marked frame number in the Piano Roll, drag the Marker outside the Piano Roll and release it
                                              • +
                                              • select some frames and then click on the "Frame#" in the Header of the Piano Roll
                                              • +
                                              • right-click on a selected frame number and choose Remove Markers in the context menu
                                              -

                                              20:29:52 Marker Remove 16-18

                                              -

                                              Used: moderately

                                              -

                                              Greenzone is not truncated.

                                              -


                                              -

                                              -

                                              -

                                              Marker Pattern

                                              -

                                              Category: Markers change

                                              -

                                              The record is created when a sequence of Markers is created using currently chosen pattern.

                                              -

                                              The name of the pattern is added to the text of the record.

                                              -

                                              Examples:

                                              -
                                                -
                                              • select some frames and then Alt + click on the "Frame#" in the Header of the Piano Roll
                                              • +

                                                20:29:52 Marker Remove 16-18

                                                +

                                                Used: moderately

                                                +

                                                Greenzone is not truncated.

                                                +


                                                +


                                                +

                                                Marker Pattern

                                                +

                                                Category: Markers change

                                                +

                                                The record is created when a sequence of Markers is created using currently chosen pattern.

                                                +

                                                The name of the pattern is added to the text of the record.

                                                +

                                                Examples:

                                                +
                                                  +
                                                • select some frames and then Alt + click on the "Frame#" in the Header of the Piano Roll
                                                -

                                                20:30:11 Marker Pattern 20-30 One Quarter (10001000...)

                                                -

                                                Used: very rarely

                                                -

                                                Greenzone is not truncated.

                                                -


                                                -

                                                -

                                                -

                                                Marker Rename

                                                -

                                                Category: Markers change

                                                -

                                                The record is created when Note of a Marker is changed.

                                                -

                                                The new text of the Note is added to the text of the record.

                                                -

                                                Examples:

                                                -
                                                  -
                                                • type the text of the Note right after creating the new Marker by double-click
                                                • -
                                                • click on the upper edit field, erase old text and type new, then press Enter or click anywhere outside the edit field
                                                • -
                                                • click on the lower edit field, erase old text and type new, then press Enter or click anywhere outside the edit field
                                                • +

                                                  20:30:11 Marker Pattern 20-30 One Quarter (10001000...)

                                                  +

                                                  Used: very rarely

                                                  +

                                                  Greenzone is not truncated.

                                                  +


                                                  +


                                                  +

                                                  Marker Rename

                                                  +

                                                  Category: Markers change

                                                  +

                                                  The record is created when Note of a Marker is changed.

                                                  +

                                                  The new text of the Note is added to the text of the record.

                                                  +

                                                  Examples:

                                                  +
                                                    +
                                                  • type the text of the Note right after creating the new Marker by double-click
                                                  • +
                                                  • click on the upper edit field, erase old text and type new, then press Enter or click anywhere outside the edit field
                                                  • +
                                                  • click on the lower edit field, erase old text and type new, then press Enter or click anywhere outside the edit field
                                                  -

                                                  20:31:01 Marker Rename 20 Testing...

                                                  -

                                                  Used: often

                                                  -

                                                  Greenzone is not truncated.

                                                  -


                                                  -

                                                  -

                                                  -

                                                  Marker Drag

                                                  -

                                                  Category: Markers change

                                                  -

                                                  The record is created after moving a Marker from one frame to another.

                                                  -

                                                  The old and new frame number, as well as the Note of the Marker, are added to the text of the record.

                                                  -

                                                  Examples:

                                                  -
                                                    -
                                                  • double-click on a marked frame number in the Piano Roll, drag the Marker to a non-marked frame number and release
                                                  • +

                                                    20:31:01 Marker Rename 20 Testing...

                                                    +

                                                    Used: often

                                                    +

                                                    Greenzone is not truncated.

                                                    +


                                                    +


                                                    +

                                                    Marker Drag

                                                    +

                                                    Category: Markers change

                                                    +

                                                    The record is created after moving a Marker from one frame to another.

                                                    +

                                                    The old and new frame number, as well as the Note of the Marker, are added to the text of the record.

                                                    +

                                                    Examples:

                                                    +
                                                      +
                                                    • double-click on a marked frame number in the Piano Roll, drag the Marker to a non-marked frame number and release
                                                    -

                                                    20:31:08 Marker Drag 20=>15 Testing...

                                                    -

                                                    Used: moderately

                                                    -

                                                    Greenzone is not truncated.

                                                    -


                                                    -

                                                    -

                                                    -

                                                    Marker Swap

                                                    -

                                                    Category: Markers change

                                                    -

                                                    The record is created when two Markers switch places.

                                                    -

                                                    The old and new frame number of the dragged Marker, as well as its Note, are added to the text of the record.

                                                    -

                                                    Examples:

                                                    -
                                                      -
                                                    • double-click on a marked frame number in the Piano Roll, drag the Marker to another marked frame number and release
                                                    • +

                                                      20:31:08 Marker Drag 20=>15 Testing...

                                                      +

                                                      Used: moderately

                                                      +

                                                      Greenzone is not truncated.

                                                      +


                                                      +


                                                      +

                                                      Marker Swap

                                                      +

                                                      Category: Markers change

                                                      +

                                                      The record is created when two Markers switch places.

                                                      +

                                                      The old and new frame number of the dragged Marker, as well as its Note, are added to the text of the record.

                                                      +

                                                      Examples:

                                                      +
                                                        +
                                                      • double-click on a marked frame number in the Piano Roll, drag the Marker to another marked frame number and release
                                                      -

                                                      20:31:14 Marker Swap 24<=>28

                                                      -

                                                      Used: rarely

                                                      -

                                                      Greenzone is not truncated.

                                                      -


                                                      -

                                                      -

                                                      -

                                                      Marker Shift

                                                      -

                                                      Category: Markers change

                                                      -

                                                      The record is created when a splicing operation didn't change Input but still shifted some Markers up or down.

                                                      -

                                                      Examples:

                                                      -
                                                        -
                                                      • insert blank frame near the end of the movie (granted that there's no buttonpresses after the frame, yet there is at least one Marker)
                                                      • -
                                                      • clone a blank frame near the end of the movie (granted that there's no buttonpresses after the frame, yet there is at least one Marker)
                                                      • -
                                                      • copy a blank frame to the Clipboard and PasteInsert it somewhere near the end of the movie (granted that there's no buttonpresses, yet there is at least one Marker)
                                                      • +

                                                        20:31:14 Marker Swap 24<=>28

                                                        +

                                                        Used: rarely

                                                        +

                                                        Greenzone is not truncated.

                                                        +


                                                        +


                                                        +

                                                        Marker Shift

                                                        +

                                                        Category: Markers change

                                                        +

                                                        The record is created when a splicing operation didn't change Input but still shifted some Markers up or down.

                                                        +

                                                        Examples:

                                                        +
                                                          +
                                                        • insert blank frame near the end of the movie (granted that there's no buttonpresses after the frame, yet there is at least one Marker)
                                                        • +
                                                        • clone a blank frame near the end of the movie (granted that there's no buttonpresses after the frame, yet there is at least one Marker)
                                                        • +
                                                        • copy a blank frame to the Clipboard and PasteInsert it somewhere near the end of the movie (granted that there's no buttonpresses, yet there is at least one Marker)
                                                        -

                                                        20:31:44 Marker Shift 21

                                                        -

                                                        Used: very rarely

                                                        -

                                                        Greenzone is not truncated.

                                                        -


                                                        -

                                                        -

                                                        -

                                                        LUA Marker Set

                                                        -

                                                        Category: Markers change

                                                        -

                                                        The record is created when a Marker appears on a frame as a result of using taseditor.setmarker() function.

                                                        -

                                                        Examples:

                                                        -
                                                          -
                                                        • run a Lua script with a taseditor.setmarker(framenum) line
                                                        • +

                                                          20:31:44 Marker Shift 21

                                                          +

                                                          Used: very rarely

                                                          +

                                                          Greenzone is not truncated.

                                                          +


                                                          +


                                                          +

                                                          LUA Marker Set

                                                          +

                                                          Category: Markers change

                                                          +

                                                          The record is created when a Marker appears on a frame as a result of using taseditor.setmarker() function.

                                                          +

                                                          Examples:

                                                          +
                                                            +
                                                          • run a Lua script with a taseditor.setmarker(framenum) line
                                                          -

                                                          20:35:14 LUA Marker Set 0

                                                          -

                                                          Used: rarely

                                                          -

                                                          Greenzone is not truncated.

                                                          -


                                                          -

                                                          -

                                                          -

                                                          LUA Marker Remove

                                                          -

                                                          Category: Markers change

                                                          -

                                                          The record is created when a Marker disappears from one frame as a result of using taseditor.removemarker() function.

                                                          -

                                                          Examples:

                                                          -
                                                            -
                                                          • run a Lua script with a taseditor.removemarker(framenum) line
                                                          • +

                                                            20:35:14 LUA Marker Set 0

                                                            +

                                                            Used: rarely

                                                            +

                                                            Greenzone is not truncated.

                                                            +


                                                            +


                                                            +

                                                            LUA Marker Remove

                                                            +

                                                            Category: Markers change

                                                            +

                                                            The record is created when a Marker disappears from one frame as a result of using taseditor.removemarker() function.

                                                            +

                                                            Examples:

                                                            +
                                                              +
                                                            • run a Lua script with a taseditor.removemarker(framenum) line
                                                            -

                                                            20:36:12 LUA Marker Remove 0

                                                            -

                                                            Used: rarely

                                                            -

                                                            Greenzone is not truncated.

                                                            -


                                                            -

                                                            -

                                                            -

                                                            LUA Marker Rename

                                                            -

                                                            Category: Markers change

                                                            -

                                                            The record is created when Note of a Marker is changed as a result of using taseditor.setnote() function.

                                                            -

                                                            The new text of the Note is added to the text of the record.

                                                            -

                                                            Examples:

                                                            -
                                                              -
                                                            • run a Lua script with a taseditor.setnote(markernum, newtext) line
                                                            • +

                                                              20:36:12 LUA Marker Remove 0

                                                              +

                                                              Used: rarely

                                                              +

                                                              Greenzone is not truncated.

                                                              +


                                                              +


                                                              +

                                                              LUA Marker Rename

                                                              +

                                                              Category: Markers change

                                                              +

                                                              The record is created when Note of a Marker is changed as a result of using taseditor.setnote() function.

                                                              +

                                                              The new text of the Note is added to the text of the record.

                                                              +

                                                              Examples:

                                                              +
                                                                +
                                                              • run a Lua script with a taseditor.setnote(markernum, newtext) line
                                                              -


                                                              -

                                                              20:37:03 LUA Marker Rename 0 Hello from Lua!

                                                              -

                                                              Used: rarely

                                                              -

                                                              Greenzone is not truncated.

                                                              -


                                                              -

                                                              -

                                                              -

                                                              LUA Change

                                                              -

                                                              Category: Input change, Markers change

                                                              -

                                                              The record is created when Input or Markers were changed as a result of using taseditor.applyinputchanges() function.

                                                              -

                                                              Instead of the word "Change" the operation can be named with any other text provided by the parameter of taseditor.applyinputchanges() function.

                                                              -

                                                              Examples:

                                                              -
                                                                -
                                                              • run a Lua script containing such lines as taseditor.submitinputchange(frame, joypad, input) and taseditor.applyinputchanges(name)
                                                              • -
                                                              • run a Lua script containing such lines as taseditor.submitinsertframes(frame, number) or taseditor.submitdeleteframes(frame, number) and taseditor.applyinputchanges(name)
                                                              • +


                                                                +

                                                                20:37:03 LUA Marker Rename 0 Hello from Lua!

                                                                +

                                                                Used: rarely

                                                                +

                                                                Greenzone is not truncated.

                                                                +


                                                                +


                                                                +

                                                                LUA Change

                                                                +

                                                                Category: Input change, Markers change

                                                                +

                                                                The record is created when Input or Markers were changed as a result of using taseditor.applyinputchanges() function.

                                                                +

                                                                Instead of the word "Change" the operation can be named with any other text provided by the parameter of taseditor.applyinputchanges() function.

                                                                +

                                                                Examples:

                                                                +
                                                                  +
                                                                • run a Lua script containing such lines as taseditor.submitinputchange(frame, joypad, input) and taseditor.applyinputchanges(name)
                                                                • +
                                                                • run a Lua script containing such lines as taseditor.submitinsertframes(frame, number) or taseditor.submitdeleteframes(frame, number) and taseditor.applyinputchanges(name)
                                                                -

                                                                20:39:56 LUA Corruptor 10

                                                                -

                                                                Used: rarely

                                                                -

                                                                Greenzone is truncated after the first frame where Input or Lag was changed.

                                                                -


                                                                -


                                                                -


                                                                -


                                                                -


                                                                +

                                                                20:39:56 LUA Corruptor 10

                                                                +

                                                                Used: rarely

                                                                +

                                                                Greenzone is truncated after the first frame where Input or Lag was changed.

                                                                +


                                                                +


                                                                +


                                                                +


                                                                +


                                                                -

                                                                Created with the Personal Edition of HelpNDoc: Free Kindle producer

                                                                -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/PianoRoll.html b/web/help/taseditor/PianoRoll.html index 249fa71c..35420cee 100644 --- a/web/help/taseditor/PianoRoll.html +++ b/web/help/taseditor/PianoRoll.html @@ -1,156 +1,348 @@ - - + + + + + - 2.1. Piano Roll - - - - - - - - - - + + + + + + + + 2.1. Piano Roll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      2.1. Piano Roll

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      2.1. Piano Roll

      + +
      +

      -

      Piano Roll

      -


      -

      -


      -

      Taseditor's workspace is similar to the interface found in many music-sequencing programs. Piano Roll is a table containing the most necessary data about the edited project. Users can both observe that data and edit it by mouse clicks on various cells of the table.

      -

      If you just opened the Taseditor window you will most likely see an empty project that contains only the starting (zeroth) frame of the movie. So, before you begin any experiments, you should temporarily unpause the emulator to let the movie reach at least the title screen of the game, the point where players can already affect the game with buttons Input. By default the hotkey to pause/unpause emulator is the Pause key on the keyboard, but in Taseditor you can use middle mouse button (the wheel) instead. Try watching the running game for a couple of seconds, then again press the Pause key or make the middle-click (anywhere) to stop emulation.

      -

      During the emulation, Piano Roll contents become filled with the information about the processed frames. Each line in the Piano Roll list is responsible for a single frame. The index number of the frame is shown at the beginning of the line, the numeration goes top-down. When the window size is not enough to display all the frames, the list gets a vertical scrollbar.

      -

      By the color of each line you can tell the following data about the corresponding frame:

      -
        -
      • Pale (almost white) lines stand for frames that are outside of the Greenzone. This means that the emulator haven't processed these frames yet and thus it knows nothing about them. For example, if you import some finished movie into Taseditor, at first Piano Roll will display all frames in whitish colors, before running through them. In the above picture such lines begin from the frame 21, because the Greenzone ends at the frame 20.
      • -
      • Green and red lines mean that those frames are contained in the Greenzone, the emulator has already played back that part of the movie, and you've already seen on the FCEUX screen what happens with the game during these frames. Lag frames are marked red, otherwise there's no difference between red and green lines.
      • -
      • The light-blue line (frame 18 on the picture) shows the currently emulated frame. Events of the frame are displayed on the FCEUX screen at the moment. This is always a sole line. In this Manual we will call it the Playback cursor. When emulator is paused, the Playback cursor stays at the same frame, and while emulation the cursor runs down, leaving the trail of green and red Greenzone frames behind. You can put the Playback cursor at any frame of the movie to see the game events of that frame. To do that, click the very left column of the Piano Roll (the column where the blue triangle pointer travels down) in the line you wish to observe – the blue pointer will jump to the chosen line along with the Playback cursor, and the FCEUX window will update accordingly, showing the in-game state of the frame. Now, if you don't let go of the left mouse button, you can drag the light-blue cursor up and down.
      • -
      • The dark-blue line highlights the selected movie segment. The actual color may differ depending on your Windows settings (the Visual theme chosen). Piano Roll lines become selected as you left-click on them. In the above picture the single frame 27 is selected, but you can select any number of frames. To select a range of frames, click on the number of the first frame and stretch the selection by dragging the mouse up or down. Note: Piano Roll lines will also be selected by clicking on the Input (i.e. almost any other column), but the column with frame numbers is specifically dedicated to working with the Selection. In this Manual we will call all dark-blue lines the Selection, and a single selected line will be called the Selection cursor. Unlike the Playback cursor, the Selection cursor isn't tied to the game state. To totally remove the Selection you could right-click the number of a selected frame and choose "Deselect" in the context menu, but usually there's no need to remove the Selection left from previous operations with the movie, because the next operation will automatically bring the Selection cursor to a new place.
      • -
      • A purple line appears for a brief moment when you use the Undo feature. This way the program shows you the exact place of the reverted changes. A huge convenience of Taseditor is that absolutely any change can be reverted with the standard key combination Ctrl + Z, so don't be afraid to experiment.
      • +

        Piano Roll

        +


        +

        +


        +

        Taseditor's workspace is similar to the interface found in many music-sequencing programs. Piano Roll is a table containing the most necessary data about the edited project. Users can both observe that data and edit it by mouse clicks on various cells of the table.

        +

        If you just opened the Taseditor window you will most likely see an empty project that contains only the starting (zeroth) frame of the movie. So, before you begin any experiments, you should temporarily unpause the emulator to let the movie reach at least the title screen of the game, the point where players can already affect the game with buttons Input. By default the hotkey to pause/unpause emulator is the Pause key on the keyboard, but in Taseditor you can use middle mouse button (the wheel) instead. Try watching the running game for a couple of seconds, then again press the Pause key or make the middle-click (anywhere) to stop emulation.

        +

        During the emulation, Piano Roll contents become filled with the information about the processed frames. Each line in the Piano Roll list is responsible for a single frame. The index number of the frame is shown at the beginning of the line, the numeration goes top-down. When the window size is not enough to display all the frames, the list gets a vertical scrollbar.

        +

        By the color of each line you can tell the following data about the corresponding frame:

        +
          +
        • Pale (almost white) lines stand for frames that are outside of the Greenzone. This means that the emulator haven't processed these frames yet and thus it knows nothing about them. For example, if you import some finished movie into Taseditor, at first Piano Roll will display all frames in whitish colors, before running through them. In the above picture such lines begin from the frame 21, because the Greenzone ends at the frame 20.
        • +
        • Green and red lines mean that those frames are contained in the Greenzone, the emulator has already played back that part of the movie, and you've already seen on the FCEUX screen what happens with the game during these frames. Lag frames are marked red, otherwise there's no difference between red and green lines.
        • +
        • The light-blue line (frame 18 on the picture) shows the currently emulated frame. Events of the frame are displayed on the FCEUX screen at the moment. This is always a sole line. In this Manual we will call it the Playback cursor. When emulator is paused, the Playback cursor stays at the same frame, and while emulation the cursor runs down, leaving the trail of green and red Greenzone frames behind. You can put the Playback cursor at any frame of the movie to see the game events of that frame. To do that, click the very left column of the Piano Roll (the column where the blue triangle pointer travels down) in the line you wish to observe – the blue pointer will jump to the chosen line along with the Playback cursor, and the FCEUX window will update accordingly, showing the in-game state of the frame. Now, if you don't let go of the left mouse button, you can drag the light-blue cursor up and down.
        • +
        • The dark-blue line highlights the selected movie segment. The actual color may differ depending on your Windows settings (the Visual theme chosen). Piano Roll lines become selected as you left-click on them. In the above picture the single frame 27 is selected, but you can select any number of frames. To select a range of frames, click on the number of the first frame and stretch the selection by dragging the mouse up or down. Note: Piano Roll lines will also be selected by clicking on the Input (i.e. almost any other column), but the column with frame numbers is specifically dedicated to working with the Selection. In this Manual we will call all dark-blue lines the Selection, and a single selected line will be called the Selection cursor. Unlike the Playback cursor, the Selection cursor isn't tied to the game state. To totally remove the Selection you could right-click the number of a selected frame and choose "Deselect" in the context menu, but usually there's no need to remove the Selection left from previous operations with the movie, because the next operation will automatically bring the Selection cursor to a new place.
        • +
        • A purple line appears for a brief moment when you use the Undo feature. This way the program shows you the exact place of the reverted changes. A huge convenience of Taseditor is that absolutely any change can be reverted with the standard key combination Ctrl + Z, so don't be afraid to experiment.
        -


        -

        To start adding and changing the movie Input, click cells of those columns to the right from the column with frame numbers. If you click an empty cell, a symbol corresponding to the real joypad button will appear there.

        -
        - - - - +


        +

        To start adding and changing the movie Input, click cells of those columns to the right from the column with frame numbers. If you click an empty cell, a symbol corresponding to the real joypad button will appear there.

        +
        +

        AA button

        -

        BB button

        -

        SSelect button

        -

        TStart button

        -

        U – D-pad Up

        -

        DD-pad Down

        -

        LD-pad Left

        -

        RD-pad Right

        -

        -
        + + + +
        +

        AA button

        +

        BB button

        +

        SSelect button

        +

        TStart button

        +

        U – D-pad Up

        +

        DD-pad Down

        +

        LD-pad Left

        +

        RD-pad Right

        +
        +

        +
        -

        If you click on an occupied cell, it will become cleared, and the corresponding button will be considered released on that frame. There is no other button states except these two: either pressed or released.

        -

        At first it might not be very trivial to correlate these 8 symbols with plastic buttons of a real joypad, but try pressing the first player input keys (set in your emulator) while you are in Taseditor. As you tap the buttons, the corresponding letters will flash in the Piano Roll Header, and you can easily associate the columns with buttons.

        -

        When working in Taseditor, the most of time is spent on that very process of setting and removing buttons at different frames. This way you form the sequence of button states, which is then fed to the game and reflected by actions of the game character(s). For example, if you put the letter "A" to a chosen Piano Roll cell at the middle of Super Mario Bros gameplay, Mario will perform a low jump, because a short A button press occurred in the movie. And if you set several "A" symbols in a row (vertically), Mario will do a high jump, because A was held longer.

        -


        -

        Every time you change the Input above the line with the Playback cursor, the light-blue cursor steps back (up in the Piano Roll) also clearing some part of the Greenzone. This happens because the change of Input leads to a change in the game events, so the game data memorized inside the Greenzone becomes irrelevant. Thus after you change Input you need to replay some frames of the movie again – either by unpausing the emulator, or by manually dragging the Playback cursor to the frame of interest – and you will see results of the latest Input changes on FCEUX screen (and also restore a part of the Greenzone).

        -

        Besides, you can hold the right mouse button and roll the mouse wheel down to move the Playback cursor to the needed frame manually. Wheel-based navigation is the most responsive way to observe a little segment of the movie. You may use a single hand, and the mouse pointer may be anywhere, e.g. it may be left over the edited Input cells. Try this method, it's a very effective way to rewind back and forth. Just hold the right mouse button with one finger and roll the wheel with another finger while looking at the FCEUX window.

        -


        -

        In addition to single cell clicks, you can also change button states in many frames at once. For instance, if you want the R button (Right) to be pressed for 20 straight frames, you don't have to click all 20 cells. You can just click on one of them, hold the left mouse button and move the mouse cursor up or down – it will leave a trail of symbols, thus you will draw a vertical row of buttonpresses. Similarly, you can quickly erase a row of symbols by clicking the first one and moving the eraser up or down. As you may notice, erasing starts when you click an occupied cell, and drawing starts when you click an empty cell.

        -

        Moreover, you can hold the Shift key before clicking on the Input to spread the effect of the click across all frames between the point of click and the Selection cursor. For example, you can set "R" in the first frame, then scroll the Piano Roll to the end, hold Shift and set "R" in the last frame – the R button press will appear in all frames.

        -

        -

        There's one more way to mass set or mass remove buttonpresses. First, select several frames, for example, the 5th, the 10th and the 20th (to do it you have to hold Ctrl while clicking on numbers 0000005, 0000010 and 0000020). Then click on the "L" letter in the Piano Roll Header. If the selected frames didn't have the Left button symbols, they will get it. And if all of the frames had the Left button already pressed, the click will clear it.

        -

        Later you will find a few other ways to edit the Input, but these were the main ones. At first it might look unnatural to draw buttonpresses with the mouse instead of simulating them using keyboard keys. But this discomfort feeling will disappear soon after you devote a few days to Taseditor.

        -

        -

        -

        When drawing the Input you've probably noticed that previously drawn letters have different color, and as you add new buttonpresses the old letters change their color from orange to violet and blue, eventually becoming standard black. This is one of experimental features of Taseditor, called "Hot Changes". It was invented to unobtrusively increase TASer's awareness about recent changes. Every time you modify the Input, the latest buttonpresses receive the hottest color (bright orange), and all the previous edits cool down by one level, becoming less bright.

        -

        Because of the coloring, even a cursory glance on the Piano Roll is enough to get the idea which buttonpresses were added just recently and which were set long ago. Also, you can see which of them were recently removed (they are replaced with a dash).

        -

        If you don't like this feature, you can disable it, but within this Guide we'll imply that you have the "Hot Changes" enabled.

        -


        -

        The narrow column to the left from the column with frame numbers is not just for dragging the Playback cursor. It also displays various informational icons. The blue arrow pointer always points to the frame where the Playback cursor is now. The green arrow pointer shows where the Playback cursor was before the Input above it has changed. And the digit cards in this column indicate Bookmarks, they will be described later.

        -

        -

        -

        The yellow marks on the numbers of some frames (frames 12 and 22 on the above picture) are called Markers. Besides the yellow color, they can be recognized by the wide font of the frame number.

        -

        Markers are meant to facilitate the movie navigation and improve TASer's self-organization. You decide how to use them on your own: whether to put them at the beginning of each level or to mark every jump, shot or any in-game event. Essentially, by setting Markers you logically break your movie down into sections, and then you can cross the movie not just by jumping from frame to frame, but from section to section. This allows you to interpret the movie on a higher level of abstraction.

        -

        Such structuring helps to keep a precise image of the entire movie in mind. That kind of an image exists in each TASer's mind, but usually it's rather fuzzy – we remember a rough sequence of the evens, but omit the details (because most of time they are insignificant). When TASer turns emulator off, the image starts to gradually become vague and forgotten. Thus at the next session one needs to re-watch his own movie from the beginning in order to refresh memories, figure key events, arrange priorities and, in general, mentally prepare for resumption of TASing. Sometimes this is needed even more often – depending on the complexity of the TAS. That's why it's recommended to consolidate that image by setting real Markers, not just in your mind but in actual movie.

        -

        A Marker can be set at any frame. Unlike the Input, Markers don't affect the game events. There are several ways to set Markers:

        -

        Example 1. Double-click on a frame number. If there was no Marker at this frame, it will appear there. If the Marker already exists, you can drag it while the left button is still held after the double-click. This way you can move any Marker to a different frame or simply dump it outside the Piano Roll, thus removing it from the movie.

        -

        Example 2. Select one or several frames by clicking the frame number(s), then click the "Frame#" label in the Piano Roll Header. If some of the selected frames didn't have Markers, they will all become marked. If all of them were already marked, all the Markers will be removed. This way you may mass set or mass remove Markers the same way as Input.

        -

        Example 3. Select one or several frames in the Piano Roll, right-click on any of the selected frame numbers and choose "Set Markers" or "Remove Markers" in the context menu. This is the slowest way, so the other two are more preferred.

        -


        -

        Any Marker operation may be undone (Ctrl + Z) anytime, just like any Input operation.

        -

        Markers are automatically numbered by the order they are located in the movie – top-down from first to last. In the upper left corner of TAS Editor window you can see the number of the Marker that is located just above the Playback cursor in the movie (light-blue "Marker #" label). This label both informs you and serves as a button for auto-scrolling. E.g. if you left the Playback cursor in one part of the movie and scrolled the Piano Roll far from that point, you can immediately return to the light-blue cursor anytime by clicking the "Marker" label (or tapping the Shift key twice). You are definitely going to need this feature when editing large movies.

        -

        A similar button can be found in the lower left corner of Taseditor. The "Marker #" label of a dark blue color (the same color as the Selection cursor) displays the number of the Marker located just above the Selection. If you click this label, the Piano Roll will automatically jump to Selection. This button is going to be used as often as the upper one. Its keyboard alternative is tapping the Ctrl key twice.

        -

        It should be easy to remember that the Shift key is almost always used to control the Playback cursor, while the Ctrl key is to control the Selection cursor.

        -

        If both Playback and Selection cursors are under the same Marker, the numbers in both corners will obviously be the same.

        -


        -

        Markers can do more than just divide the movie into logical parts. They may also contain text records (comments and work notes). The Marker Note is displayed right near its number. The upper edit field contains the Note of the Marker above the Playback Cursor, and the lower field shows the Note of the Marker above the Selection cursor.

        -

        By default, every new Marker contains an empty Note. When you create a new Marker by double-click, the lower edit field automatically becomes active, because the Selection cursor points to the just marked frame. So you may quickly type any text for the Note of that Marker and then resume your work with the movie. Text changes are saved automatically.

        -

        You can edit an old Marker Note in any of the following ways:

        -
          -
        • Put the Selection cursor to that frame and click the lower edit field to activate it.
        • -
        • Simply double-click on the Marker, and the lower edit field will activate automatically.
        • -
        • Put the Playback cursor to that frame and click the upper edit field to activate it.
        • +

          If you click on an occupied cell, it will become cleared, and the corresponding button will be considered released on that frame. There is no other button states except these two: either pressed or released.

          +

          At first it might not be very trivial to correlate these 8 symbols with plastic buttons of a real joypad, but try pressing the first player input keys (set in your emulator) while you are in Taseditor. As you tap the buttons, the corresponding letters will flash in the Piano Roll Header, and you can easily associate the columns with buttons.

          +

          When working in Taseditor, the most of time is spent on that very process of setting and removing buttons at different frames. This way you form the sequence of button states, which is then fed to the game and reflected by actions of the game character(s). For example, if you put the letter "A" to a chosen Piano Roll cell at the middle of Super Mario Bros gameplay, Mario will perform a low jump, because a short A button press occurred in the movie. And if you set several "A" symbols in a row (vertically), Mario will do a high jump, because A was held longer.

          +


          +

          Every time you change the Input above the line with the Playback cursor, the light-blue cursor steps back (up in the Piano Roll) also clearing some part of the Greenzone. This happens because the change of Input leads to a change in the game events, so the game data memorized inside the Greenzone becomes irrelevant. Thus after you change Input you need to replay some frames of the movie again – either by unpausing the emulator, or by manually dragging the Playback cursor to the frame of interest – and you will see results of the latest Input changes on FCEUX screen (and also restore a part of the Greenzone).

          +

          Besides, you can hold the right mouse button and roll the mouse wheel down to move the Playback cursor to the needed frame manually. Wheel-based navigation is the most responsive way to observe a little segment of the movie. You may use a single hand, and the mouse pointer may be anywhere, e.g. it may be left over the edited Input cells. Try this method, it's a very effective way to rewind back and forth. Just hold the right mouse button with one finger and roll the wheel with another finger while looking at the FCEUX window.

          +


          +

          In addition to single cell clicks, you can also change button states in many frames at once. For instance, if you want the R button (Right) to be pressed for 20 straight frames, you don't have to click all 20 cells. You can just click on one of them, hold the left mouse button and move the mouse cursor up or down – it will leave a trail of symbols, thus you will draw a vertical row of buttonpresses. Similarly, you can quickly erase a row of symbols by clicking the first one and moving the eraser up or down. As you may notice, erasing starts when you click an occupied cell, and drawing starts when you click an empty cell.

          +

          Moreover, you can hold the Shift key before clicking on the Input to spread the effect of the click across all frames between the point of click and the Selection cursor. For example, you can set "R" in the first frame, then scroll the Piano Roll to the end, hold Shift and set "R" in the last frame – the R button press will appear in all frames.

          +

          +

          There's one more way to mass set or mass remove buttonpresses. First, select several frames, for example, the 5th, the 10th and the 20th (to do it you have to hold Ctrl while clicking on numbers 0000005, 0000010 and 0000020). Then click on the "L" letter in the Piano Roll Header. If the selected frames didn't have the Left button symbols, they will get it. And if all of the frames had the Left button already pressed, the click will clear it.

          +

          Later you will find a few other ways to edit the Input, but these were the main ones. At first it might look unnatural to draw buttonpresses with the mouse instead of simulating them using keyboard keys. But this discomfort feeling will disappear soon after you devote a few days to Taseditor.

          +


          +

          When drawing the Input you've probably noticed that previously drawn letters have different color, and as you add new buttonpresses the old letters change their color from orange to violet and blue, eventually becoming standard black. This is one of experimental features of Taseditor, called "Hot Changes". It was invented to unobtrusively increase TASer's awareness about recent changes. Every time you modify the Input, the latest buttonpresses receive the hottest color (bright orange), and all the previous edits cool down by one level, becoming less bright.

          +

          Because of the coloring, even a cursory glance on the Piano Roll is enough to get the idea which buttonpresses were added just recently and which were set long ago. Also, you can see which of them were recently removed (they are replaced with a dash).

          +

          If you don't like this feature, you can disable it, but within this Guide we'll imply that you have the "Hot Changes" enabled.

          +


          +

          The narrow column to the left from the column with frame numbers is not just for dragging the Playback cursor. It also displays various informational icons. The blue arrow pointer always points to the frame where the Playback cursor is now. The green arrow pointer shows where the Playback cursor was before the Input above it has changed. And the digit cards in this column indicate Bookmarks, they will be described later.

          +


          +

          The yellow marks on the numbers of some frames (frames 12 and 22 on the above picture) are called Markers. Besides the yellow color, they can be recognized by the wide font of the frame number.

          +

          Markers are meant to facilitate the movie navigation and improve TASer's self-organization. You decide how to use them on your own: whether to put them at the beginning of each level or to mark every jump, shot or any in-game event. Essentially, by setting Markers you logically break your movie down into sections, and then you can cross the movie not just by jumping from frame to frame, but from section to section. This allows you to interpret the movie on a higher level of abstraction.

          +

          Such structuring helps to keep a precise image of the entire movie in mind. That kind of an image exists in each TASer's mind, but usually it's rather fuzzy – we remember a rough sequence of the evens, but omit the details (because most of time they are insignificant). When TASer turns emulator off, the image starts to gradually become vague and forgotten. Thus at the next session one needs to re-watch his own movie from the beginning in order to refresh memories, figure key events, arrange priorities and, in general, mentally prepare for resumption of TASing. Sometimes this is needed even more often – depending on the complexity of the TAS. That's why it's recommended to consolidate that image by setting real Markers, not just in your mind but in actual movie.

          +

          A Marker can be set at any frame. Unlike the Input, Markers don't affect the game events. There are several ways to set Markers:

          +

          Example 1. Double-click on a frame number. If there was no Marker at this frame, it will appear there. If the Marker already exists, you can drag it while the left button is still held after the double-click. This way you can move any Marker to a different frame or simply dump it outside the Piano Roll, thus removing it from the movie.

          +

          Example 2. Select one or several frames by clicking the frame number(s), then click the "Frame#" label in the Piano Roll Header. If some of the selected frames didn't have Markers, they will all become marked. If all of them were already marked, all the Markers will be removed. This way you may mass set or mass remove Markers the same way as Input.

          +

          Example 3. Select one or several frames in the Piano Roll, right-click on any of the selected frame numbers and choose "Set Markers" or "Remove Markers" in the context menu. This is the slowest way, so the other two are more preferred.

          +


          +

          Any Marker operation may be undone (Ctrl + Z) anytime, just like any Input operation.

          +

          Markers are automatically numbered by the order they are located in the movie – top-down from first to last. In the upper left corner of TAS Editor window you can see the number of the Marker that is located just above the Playback cursor in the movie (light-blue "Marker #" label). This label both informs you and serves as a button for auto-scrolling. E.g. if you left the Playback cursor in one part of the movie and scrolled the Piano Roll far from that point, you can immediately return to the light-blue cursor anytime by clicking the "Marker" label (or tapping the Shift key twice). You are definitely going to need this feature when editing large movies.

          +

          A similar button can be found in the lower left corner of Taseditor. The "Marker #" label of a dark blue color (the same color as the Selection cursor) displays the number of the Marker located just above the Selection. If you click this label, the Piano Roll will automatically jump to Selection. This button is going to be used as often as the upper one. Its keyboard alternative is tapping the Ctrl key twice.

          +

          It should be easy to remember that the Shift key is almost always used to control the Playback cursor, while the Ctrl key is to control the Selection cursor.

          +

          If both Playback and Selection cursors are under the same Marker, the numbers in both corners will obviously be the same.

          +


          +

          Markers can do more than just divide the movie into logical parts. They may also contain text records (comments and work notes). The Marker Note is displayed right near its number. The upper edit field contains the Note of the Marker above the Playback Cursor, and the lower field shows the Note of the Marker above the Selection cursor.

          +

          By default, every new Marker contains an empty Note. When you create a new Marker by double-click, the lower edit field automatically becomes active, because the Selection cursor points to the just marked frame. So you may quickly type any text for the Note of that Marker and then resume your work with the movie. Text changes are saved automatically.

          +

          You can edit an old Marker Note in any of the following ways:

          +
            +
          • Put the Selection cursor to that frame and click the lower edit field to activate it.
          • +
          • Simply double-click on the Marker, and the lower edit field will activate automatically.
          • +
          • Put the Playback cursor to that frame and click the upper edit field to activate it.
          -

          When typing a Note, press Enter or just click any unrelated element of TAS Editor window to finish editing. If you changed your mind, press Esc to cancel the editing. All the controls when editing Notes are listed in the Reference.

          -

          It is recommended to enter Notes when creating Markers, so you won't forget why the Marker was set there. This won't take much time if you set Markers by double-clicks and type laconic messages at the same second.

          -


          -

          Proceed to the Toolbox description

          -


          -


          -


          -


          -


          +

          When typing a Note, press Enter or just click any unrelated element of TAS Editor window to finish editing. If you changed your mind, press Esc to cancel the editing. All the controls when editing Notes are listed in the Reference.

          +

          It is recommended to enter Notes when creating Markers, so you won't forget why the Marker was set there. This won't take much time if you set Markers by double-clicks and type laconic messages at the same second.

          +


          +

          Proceed to the Toolbox description

          +


          +


          +


          +


          +


          -

          Created with the Personal Edition of HelpNDoc: Full-featured Documentation generator

          -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/ProgramCustomization.html b/web/help/taseditor/ProgramCustomization.html index 0abf72b5..2145499f 100644 --- a/web/help/taseditor/ProgramCustomization.html +++ b/web/help/taseditor/ProgramCustomization.html @@ -1,283 +1,455 @@ - - + + + + + - 5. Program customization - - - - - - - - - - + + + + + + + + 5. Program customization + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      5. Program customization

      - -
      - Beginner's Guide ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      5. Program customization

      + +
      +

      -

      Program customization

      -


      -


      -

      Certain useful features of Taseditor are disabled by default, because using them requires understanding of their working principles. This chapter describes all Taseditor options and settings, as well as FCEUX settings that affect your work in Taseditor.

      -

      Settings are kept in the fceux.cfg file in the emulator's main folder. If you delete this file, all settings will reset to default values when you launch FCEUX.

      -
      - - - - +

      Program customization

      +


      +


      +

      Certain useful features of Taseditor are disabled by default, because using them requires understanding of their working principles. This chapter describes all Taseditor options and settings, as well as FCEUX settings that affect your work in Taseditor.

      +

      Settings are kept in the fceux.cfg file in the emulator's main folder. If you delete this file, all settings will reset to default values when you launch FCEUX.

      +
      +

      First, if you've already read the chapter 2 and understood the purpose of all GUI elements, you should disable pop-up tooltips (intended for newbies only). Go to the "Help" submenu of Taseditor main menu and uncheck the option "Enable Tooltips". Before doing it you may want to actually read all the tooltips by pointing the mouse cursor at different elements of TAS Editor window, and thus consolidate your knowledge of the GUI.

      -

      -
      + + + +
      +

      First, if you've already read the chapter 2 and understood the purpose of all GUI elements, you should disable pop-up tooltips (intended for newbies only). Go to the "Help" submenu of Taseditor main menu and uncheck the option "Enable Tooltips". Before doing it you may want to actually read all the tooltips by pointing the mouse cursor at different elements of TAS Editor window, and thus consolidate your knowledge of the GUI.

      +
      +

      +
      -

      Now open the "View" submenu.

      -

      -

      The "Find Note window" brings up the window dedicated to searching text in Marker Notes. This function is useful when you're documenting your movie with Notes. It's described in the next chapter.

      -

      Then there are several checkboxes allowing to customize the program interface. To try the customization possibilities, create a test project and experiment with it.

      -


      -

      -

      -

      View -> Display Branch Screenshots

      -

      Displays pop-up screenshots when you point mouse cursor over Bookmarks. The screenshot helps you to recall movie events saved to the Bookmark, which simplifies searching for the needed branch of the movie, as you don't have to actually load the Bookmark when you need to have an idea on its contents. This way you can also quickly compare results of several alternative approaches.

      -

      This option is enabled by default. If disabled, no screenshots will pop up on mouse hover.

      -

      It's recommended to have it enabled, unless you're annoyed with pop-up pictures partially obstructing the view on the Piano Roll.

      -

      -

      -

      View -> Display Branch Descriptions

      -

      Displays pop-up descriptions when you point mouse cursor over Bookmarks. The text, as well as the screenshot, gives you additional information about the contents of the Bookmark, helping to decide whether this branch should be loaded or not.

      -

      The description text is taken from the Marker above the frame of that Bookmark. The Marker itself may be actually removed from the working movie long ago, but if the Bookmark was created while the Marked existed, then this Marker still exists in the branch of this Bookmark. And if you load this Bookmark, the Marker will reappear on its place.

      -

      So, when trying alternative strategies of playing through a large segment (e.g. whole level of the game), before saving every approach to a separate branch, you can make a name for the approach by setting a Marker at the Playback cursor position and typing a text message like "here I chose upper way" or just "upper way". After that, save a Bookmark on that frame. Then you can remove the Marker together with the Input of the old approach and create next approach by applying another strategy of playing the segment. When the new approach if finished and replayed, you can again create a Marker with a Note like "here I chose lower way" and save all that to another Bookmark. After that you can save the project and, say, close Taseditor. Next day you can easily recall all pros and cons of the two strategies you tried. Each Bookmark will show you the screenshot of the bookmarked frame and the text you wrote for that Bookmark. While it can be hard to distinguish the strategies by screenshots (since both approaches end at the same event of the game), but text descriptions will make them easy to recognize.

      -

      This option is enabled by default. If disabled, no descriptions will pop up on mouse hover.

      -

      It's recommended to have it enabled, unless you're annoyed with pop-up text fields.

      -

      -

      -

      View -> Enable Hot Changes

      -

      Switches the Hot Changes feature on and off.

      -

      Enabled by default. If disabled, all buttonpress symbols will be displayed in a standard black color. Otherwise, each symbol will have its own level of "hotness", depending on how long ago the corresponding Piano Roll cell was edited. Recently modified buttonpresses are more hot, so they are displayed by more intense shade of red. As the hotness decreases, the symbol colors become darker (more cold) and finally turn into standard black.

      -


      -

      -


      -

      In total, Taseditor supports 15 shades of hotness + zeroth black color. When you change the state of an Input cell, it receives maximum hotness value (15), and all the previously edited cells cool down by 1. Thereby you only need a quick look at the Piano Roll to get an idea which edits were done just recently and which were done before, or long ago.

      -

      Also, with Hot Changes you can see which buttonpresses were recently removed – instead of an empty cell there will be a dash of the corresponding color. The dash also changes its color while cooling down, and after 15 levels it finally disappears.

      -

      The same dashes appear when you insert new frames in the movie.

      -

      It's recommended to enable this feature to increase the usability of Taseditor. In theory it should even increase your working speed, because this way you never have to recall which actions you did a minute ago. Of course even without Hot Changes you can always remind the sequence of last actions by reverting History (making several Ctrl + Z keypresses) and then returning the movie to normal state again (making as many Ctrl + Y keypresses). But in this case you will also truncate the Greenzone. So better just leave the Hot Changes enabled.

      -

      The only downside of this feature is that Hot Changes data will be stored in the History Log and in FM3 project file, thus increasing the amount of occupied memory.

      -

      -

      -

      View -> Follow undo context

      -

      Scrolls the Piano Roll to relevant place every time you make an undo or redo. A purple pointer appears on the modified frame for a brief moment, thus drawing your attention to the movie changes.

      -

      This option is enabled by default. If disabled, the Piano Roll won't automatically scroll to the purple pointer.

      -

      It's recommended to have it enabled, in order to be able to backtrack undos. Usually, right after you revert an operation you want to make another edit on the same frame or nearby, so the autoscrolling is useful.

      -

      -

      -

      View -> Follow Marker Note context

      -

      Scrolls the Piano Roll to relevant Marker when you start editing its Note. For example, when you click the upper edit field to start editing the Note of the Marker above the Playback cursor, Piano Roll jumps to that Marker, allowing you to see its context (neighbor Markers and Input). And when you click the lower edit field (a Note above the Selection cursor), Piano Roll scrolls to the Marker above the Selection. This way you can observe the surroundings of the relevant Marker while editing its Note.

      -

      This option is enabled by default. If disabled, the Piano Roll won't automatically scroll to the Markers.

      -

      It's recommended to have it enabled.

      -


      -

      And the View settings are over. During your future work you likely won't need to change these checkboxes.

      -

      -

      Now open the "Config" submenu. Options listed in this menu affect Taseditor workflow more significantly. You may need reconfiguring some of them more than once.

      -

      -

      -

      Config -> Project file saving options

      -

      Opens the dialog window where you can configure the autosave function and select which aspects should be saved to FM3 files.

      -

      Taseditor has the feature of automatically saving current project to disk when user doesn't save it manually (Ctrl + S) for too long. Before Taseditor, TASers saved their movie to disk every time they saved a savestate. But Taseditor projects store much more data, and saving FM3 files can take several seconds, so it's not reasonable to resave them too often.

      -

      The default autosave period is 15 minutes. This means, if you've made some substantial changes to the project (e.g. you edited Input, and an asterisk appeared in the TAS Editor window caption), and then didn't save project for 15 minutes, Taseditor will remind you about that or just execute saving itself, depending on the state of the "silently" checkbox. If the checkbox is enabled, Taseditor silently saves the project to disk under the same filename. If it is disabled, Taseditor brings up the "Save As" dialog, where you can confirm the saving or cancel it. In the latter case Taseditor will wait another period of time until reminding you about the unsaved data.

      -

      The autosave function only works when current project already has a filename.

      -

      Maximum possible value of the period is 1440 minutes (24 hours). You can disable this function by switching off the "Autosave project" checkbox, but that's not recommended.

      -

      -

      -

      Config -> Set max undo levels

      -

      Specifies the maximum number of undo steps, how many times you can restore previous state of the project by pressing Ctrl + Z.

      -

      The History Log needs a lot of computer memory and takes some disk space to save FM3 files. The whole Log is stored in project files in compressed state. The compression is done in background – when the emulator is idle, Taseditor gradually compresses new items of the History Log. Thanks to this behavior, the History Log size doesn't affect FM3 saving time much.

      -

      With this setting you can adjust the amount of memory occupied by History Log. By default you have 100 undo levels, which means you can revert up to hundred of recent movie edits. It's not very much, because during real TASing you make lots of various edits within a small time span, as the time runs imperceptibly. If your computer has enough RAM, you can increase the "max undo levels" value up to the maximum possible number – 1000.

      -

      -

      -

      -

      Config -> Set Greenzone capacity

      -

      Defines the maximum size of the Greenzone. The Greenzone is used for easier Playback cursor navigation, allowing to instantly return to any frame that has been emulated. It needs a lot of computer memory to store emulator's information and a lot of disk space for saving FM3 projects.

      -

      The more of green and red frames there are in the Piano Roll, the more memory the Greenzone occupies. For most NES games 1 frame costs about 10 kilobytes (compressed data). So, big movie projects may take hundreds of megabytes. It affects the project loading and saving time.

      -

      To decrease the amount of needed memory, Taseditor regularly cleans the Greenzone tail, forgetting the info about segments that are too far from the Playback cursor.

      -

      This cleaning doesn't mean the Greenzone becomes inaccessible (white) on those frames. That would be very inconvenient, because to replay these frames you would need to wait until the emulation runs from the beginning of the movie. To avoid such inconvenience and still free some memory from old Greenzone sections, Taseditor uses gradual rarefication of the Greenzone tail.

      -

      This process works like shown on the picture to the right. The light-blue cursor runs down along the Piano Roll. The cursor is the head of the Greenzone. It leaves green/red lines behind, but far above it some of the lines become pale again. At first, every odd frame is cleared, then 3 of every 4, then 7 of 8, and finally 15 of 16.

      -

      Thus the Greenzone tail contains many hollow sections. And if you decide to send emulator to a frame inside such hollow section, you'll need to wait while emulation runs to it from the nearest bright Greenzone frame. But since bright frames alternate every 2 or 4 frames, the waiting will only last a split second, so you won't likely notice the difference between jumping to a regular Greenzone frame (instant jump) and jumping to a cleared tail (instant seeking).

      -

      By adjusting the "Set greenzone capacity" setting you can specify how many Greenzone frames (starting from its head) must stay untouched. On the picture to the right this number is 8.

      -

      For an experiment, choose the "Set greenzone capacity" item, a dialog window will appear asking you to enter a number, type 100 and press OK. This will mean that first hundred of frames above the Playback cursor should not be cleaned. Any cursor navigation along this area will be instant, so you may drag the light-blue cursor and use rewind with maximum comfort. After the first hundred of frames the cleaning will be removing every other frame – you'll see alternation of bright and pale lines in the Piano Roll. This alternation will last for about 200 frames. The Playback cursor navigation along the area of 200 frames will also be almost instant.

      -

      This way the Greenzone covers 100 + 200 = 300 frames, while only 100 + 100 = 200 frames are stored in memory. Then, during next 400 frames, every filled line will alternate with 3 cleared lines, and so on. In total, the Greenzone will only occupy memory needed for storing the data of 500 frames (about 5 MB), while the accessible area will be 3100 frames (about a minute).

      -

      By default, the Greenzone capacity is 10000 frames. This should be enough for most TASes. It's recommended to TAS with no less than 1000 frames of Greenzone capacity, because the further economy would be impractical.

      -

      The maximum number for that parameter is 50000.

      -

      -

      -

      Config -> Enable Greenzoning

      -

      Controls the process of collecting data to the Greenzone.

      -

      If the option is enabled, every new frame is saved into the Greenzone right after it has been emulated. This is intended behavior of Taseditor, so the option is enabled by default.

      -

      Disabling this option may be useful in rare cases, for example, when running bots which need high performance. But in normal situations it's recommended to have this function enabled.

      -

      -

      -

      Config -> Autofire Pattern skips Lag

      -

      Accounts for lag when you're using patterns (Alt + clicks on Input).

      -

      If the option is disabled, patterns appear in the Piano Roll exactly like they were coded (e.g. for the pattern "Alternating (1010...)" the new buttonpresses will indeed alternate one after another).

      -

      If the option is enabled, the resulting sequence of buttonpresses may differ from original pattern (lag frames will have additional gaps not present in the pattern).

      -

      Since lag frames aren't accounted by most games, you have to skip red lines of the Piano Roll to correctly calculate the gaps between presses. For instance, if there must be exactly 3 blank frames between every buttonpress (pattern "10001000"), but there's also one lag frame in the middle of current segment, you have to add 1 more blank frame  (100001000).

      -

      This option is enabled by default. It's recommended to leave it enabled, because in vast majority of cases you'll need to skip lag frames, in order to adapt buttonpresses to how the game interprets Input.

      -

      -

      -

      Config -> Auto-adjust Input according to Lag

      -

      Enables automatic adjustment of Input according to changes of lag data.

      -

      Basically, games only care about Input at green lines of the Piano Roll. It's pointless to draw any Input on red lines, because during lag frames the game doesn't poll Input. Those frames simply don't exist from the point of view of the game engine.

      -

      When you edit Input, you change the flow of game events, and lag may appear on different frames too. If those frames previously had a meaningful Input, this Input must be shifted to the frames without lag, to allow it to affect the game.

      -

      If this checkbox is enabled, you won't have to adjust the Input manually every time the Lag appears on different frames. Taseditor will insert an extra line at every new lag frame, thus shifting Input 1 frame down. And when an old lag frame disappears, Taseditor will remove respective frames from the movie, thus shifting Input up. As a result, you can be sure that the game will always perceive your old Input correctly, no matter any Lag changes.

      -

      Auto-adjustment operations are done by Taseditor only when you're watching (emulating) a segment, i.e. when Playback cursor runs through pale Piano Roll lines. The result of these operations is saved into the current History Log item.

      -

      This feature is enabled by default, and it's recommended to always work with the function enabled. It significantly increases the comfort of TASing, especially when dealing with lag-heavy games.

      -

      -

      -

      Config -> Draw Input by dragging

      -

      Allows to literally draw Input by holding the left mouse button and moving the mouse cursor over the Piano Roll.

      -

      This option is enabled by default, so you can quickly draw or erase a long line of buttonpresses.

      -

      Drawing/erasing is usually constrained by single column, which allows user to do sweeping motions with the mouse. But if you hold the Shift key while drawing, you will be able to draw/erase Input freely (it's rather impractical, but fun).

      -

      If you disable this option, your clicks will only set/unset single buttonpresses. It may be necessary, for example, if you have trembling hands. But otherwise enabling this feature is recommended.

      -

      -

      -

      Config -> Combine consecutive Recordings/Draws

      -

      Combines consecutive operations of Input Recording into single item of the History Log. Also combines all Input drawn with the same press of mouse button.

      -

      This feature is disabled by default. So when you're recording Input, every recorded frame will create a separate item in the History Log, and you can undo changes for any frame. Also, when you're drawing Input, every new stroke will create a new History Log item, and you can undo each of them separately.

      -

      However, in real TASing you don't need such precision of the undo. In fact, it may even become irritating when you have to undo every buttonpress separately. So, to save considerable amount of space in History Log, it's recommended to enable this option.

      -

      -

      -

      Config -> Use 1P keys for all single Recordings

      -

      Allows to record any joypad Input using only the first gamepad (1P). This function is used when you record Input traditional way using multitracking method to take turns for different players, e.g. first you record a short segment of Input for player one (1P), then record the Input for 2P and so on.

      -

      Thanks to multitracking, you don't have to press buttons on both controllers at once. And with the "Use 1P keys for all single Recordings" option you don't even have to configure 2P controls, because the same keys used for 1P can be used for all the rest joypads too.

      -

      The option is enabled by default. If you disable it, emulator will use the second controller keys for recording 2P.

      -

      It's recommended to have it enabled, in order to save the space on the keyboard.

      -

      -

      -

      Config -> Use Input keys for Column Set

      -

      Allows editing Input in selected frames by pressing corresponding joypad keys.

      -

      This feature is intended to speed up the Input editing process. To mass-set/mass-unset buttonpresses in a given segment, you usually either draw with mouse, or select a range of frames and click the necessary symbol in the Piano Roll Header – the symbol flashes and the respective Input changes in all the selected frames.

      -

      With the "Use Input keys for Column Set" option you can press real keys (assigned to joypads) instead of clicking the Piano Roll Header. The result will be the same.

      -

      The option is disabled by default. Turn it on if you mostly use the new TASing methods and don't record Input traditional way. But when you're using Recording, either disable it or just remove the Selection to avoid Input changes on the selected frames when pressing joypad buttons.

      -

      With this feature you can record joypad buttons even when Recording is off. Put the Selection cursor to the frame you want to apply Input to, and press the needed joypad buttons.

      -

      Multitracking mode in this case works the same way as with regular Recording. For example, if the "2P" radiobutton is chosen at the moment, pressing the key assigned to the A button will only record Input for the "A" column of the 2nd player.

      -

      -

      -

      Config -> Bind Markers to Input

      -

      Attaches Markers to Input. If the option is enabled, various Input editing functions will also affect Markers. For example, inserting blank frames into the movie will shift down both Input and Markers.

      -

      Usually Markers are set to frames where certain in-game events occur. And when you improve previous result and reach the given place earlier than before, the corresponding Marker (set there after previous attempt) should point to an earlier frame now. Sometimes you have to drag such Markers manually. But thanks to the binding feature, Markers will shift themselves during Input modifications, so the manual adjustment of Markers is rarely needed.

      -

      Detaching Markers may be necessary when you need to edit Input without shifting Markers. For example, when you need to remove a part of Input, leaving Markers intact.

      -

      The option is on by default. It's recommended to work with attached Markers most of the time, temporarily detaching them when necessary.

      -

      For clarification, Taseditor highlights attached Markers with a pale yellow color, and detached Markers with more bright yellow.

      -

      -

      -

      Config -> Empty new Marker Notes

      -

      Defines the default Notes text. If the option is set, each newly created Marker will have an empty Note. If not set, the new Marker will copy the above Marker's Note text.

      -

      The option is enabled by default. It's recommended to left it on and type original Notes for important Markers, thus not leaving all Notes blank.

      -

      -

      -

      Config -> Old control scheme for Branching

      -

      Imitates certain limitations of the traditional TASing method, particularly related to handling the Bookmarks (savestates).

      -

      The option is disabled by default, so hotkeys F1-F10 are used to load branch of the the corresponding Bookmarks, and the numeric keys 1-10 are used for simple jumps to bookmarked frames without changing the movie.

      -

      Also, Input Recording is switched on with a simple press of the Toggle Read-Only hotkey.

      -

      But if you enable this option, the controls scheme will be the same as in old emulators. Pressing F1-F10 will work depending on the Recording mode. When the Recording is off, functional keys jump to respective Bookmark frame, and when Recording is on, F1-F10 keys load the branch of the Bookmark.

      -

      Also, Input Recording won't work until you load some Bookmark. This behavior allows you to press the Toggle Read-Only hotkey in the middle of watching the movie, without overwriting old Input until you actually load a savestate.

      -

      Plus, there will be a red frame around the "current slot" number in the Bookmarks List. Press numeric keys 1-10 to switch the current slot.

      -

      This option is only left here to help old TASers move to Taseditor. But it's recommended to use the new controls scheme, because it fits the specifics of TASing process in Taseditor much better.

      -

      -

      -

      Config -> Branches restore entire Movie

      -

      Defines the way a branch is restored when you load its Bookmark.

      -

      The option is enabled by default, so when you're loading a Bookmark, you replace the current movie with the movie state stored in that Bookmark.

      -

      If this option is disabled, when you're loading a Bookmark, the current movie is replaced with a truncated version of the bookmarked movie state. The movie will be truncated at the bookmarked frame, thus imitating the traditional behavior of loading a savestate: savestates only recover the part of the movie before the Playback cursor, and the rest frames (from the light-blue cursor to the movie end) aren't loaded. This makes sense when TASing traditional way, because after loading a savestate TASer usually records a new Input starting from the position of the Playback cursor, so there's no need to load the data that is going to be be overwritten anyway. But in Taseditor the movie is edited independently from the Playback cursor position, so you can load the entire movie state from Bookmarks, without caring if the Playback cursor is in the end of the movie or it is in the middle.

      -

      It's recommended to leave this option enabled.

      -

      -

      -

      Config -> HUD in Branch screenshots

      -

      Defines the way to capture screenshots when creating Bookmarks.

      -

      If the option is on, it takes a snapshot of the whole emulator window, including icons and emulator messages, Lua output and other data placed over the game picture. If the option is disabled, Bookmarks will only capture the game output.

      -

      The option is enabled by default. It's recommended to leave it on, in order to use Lua output and frame counter when comparing alternate approaches to playing through a segment.

      -

      -

      -

      Config -> Autopause at the end of Movie

      -

      Automatically stops movie playback at the last frame, unless it started playing from the last frame.

      -

      When replaying a finished (or partially finished) movie, you usually don't want to pass over the boundary of its Input. That's why the "Autopause at the end of Movie" option is enabled by default. If you disable it, the emulator will play infinitely after the current movie Input ended, expanding the movie size until you press Pause or the middle mouse button.

      -

      It's recommended to leave this option enabled.

      -


      -
      -

      -

      -

      Now you are aware of all Taseditor settings, the remaining part of the chapter describes FCEUX emulator settings that may be useful for a TASer.

      -


      -

      If you are going to TAS traditional way, it's obligatory to set the first controller buttons to such keys that would be easy to press together with the Frame Advance hotkey. While FCEUX supports binding the virtual NES joypad to a real PC gamepad, it's recommended to use the keyboard for recording Input, in order to have fast access to Frame Advance, Frame Rewind, Pause, and to all 10 savestate slots.

      -

      However, if you use Taseditor as intended, you won't need to use Recording too much, and even in cases when you use it (for example, when recording a test playthrough of a level), an access to functional keys isn't critical. So, you can reassign the game controls to a USB gamepad, if you have one.

      -

      Virtual controller buttons are configured in FCEUX the following way. Choose Config -> Input in emulator main menu. In the appeared dialog, select the "Gamepad" item from the leftmost drop-down listbox (usually it's already selected). Click the left Configure button (since you need to configure the first gamepad). In the new window click the Up button, then a small window will appear, now press the keyboard key you want to set for the virtual Up button. Press that key 2nd time to confirms your choice, or just click Close. Then you need to do the same for the rest buttons of NES gamepad – Down, Left, Right, Select, Start, B, A. After you're done with the first controller buttons (Virtual Gamepad 1), you may close both windows: Gamepad and Input Configuration.

      -

      You can check the assigned buttons while playing the game or while Taseditor is engaged – as you press them, the corresponding symbols in the Piano Roll Header will shine with green color. Besides, if you enable Input display (FCEUX: Config -> Display -> Input Display -> 2 player), FCEUX screen will show you the pressed buttons too.

      -

      In addition to recording the regular gaming session, virtual gamepad buttons may be used to quickly set Input when editing movie (see Config -> Use Input keys for Column Set). Select a range of frames where you want to change Input and press the key you assigned to a button of the virtual gamepad.

      -

      When you map the virtual buttons to keyboard keys, make sure none of the emulator or Taseditor hotkeys are already assigned to those keys. The full list of default hotkeys can be found in the Reference.

      -

      Some FCEUX hotkeys don't have default mapping (they're not mapped to any key yet). You can configure them the following way. In the emulator main menu choose Config -> Map Hotkeys. A window listing all possible emulator hotkeys will appear. Choose the necessary hotkey, double-click it and then press the desired keyboard key.

      -

      First of all, find the item called "Open TAS Editor" and double-click it. In the appeared window press the key that you will always use to quickly launch Taseditor.

      -

      Second, find the item "Reload ROM or TAS Editor Project" and either remap it or remember the default combination (Ctrl + F1). This hotkey will help you quickly return to your interrupted work – just launch FCEUX, press the Reload ROM hotkey, then press the aforementioned Open TAS Editor hotkey, and then again Reload ROM (this time it will work as Reload TAS Editor Project). This way you'll return to the state of your paused work in a split second.

      -

      Now look at the hotkeys "Frame Advance" и "Frame Rewind". They are used for Playback cursor navigation. By default they are mapped to "\" and "Backspace". You can reconfigure them to more handy keys or just use the mouse wheel for the Playback cursor frame-by-frame navigation.

      -

      Also see the "Speed Down" and "Speed Up" hotkeys. You may consider remapping them to Numpad keys "+" and "-".

      -

      The "Pause" и "Restore Playback" hotkeys are set to "Pause/Break" and "Spacebar" keys by default, but in most cases it's easier to use the middle mouse button instead of these hotkeys, so you can even reassign the "Spacebar" for something else if you wish.

      -

      Finally, there is the "Cancel Seeking" hotkey ("Esc" key by default). Pressing it is the same as clicking the Taseditor progressbar – if the Playback was seeking to a target frame, the seeking will be aborted.

      -

      Some FCEUX hotkeys don't work when Taseditor is engaged. For example, the "Open ROM" won't work – you have to load ROM before running Taseditor. This is done for mistake-proofing.

      -


      -

      The next chapter describes additional features of Taseditor. You may postpone reading it until you are used to main features. Anyway, now you're ready enough for productive work in Taseditor.

      -


      -


      -


      -


      -


      +

      Now open the "View" submenu.

      +

      +

      The "Find Note window" brings up the window dedicated to searching text in Marker Notes. This function is useful when you're documenting your movie with Notes. It's described in the next chapter.

      +

      Then there are several checkboxes allowing to customize the program interface. To try the customization possibilities, create a test project and experiment with it.

      +


      +


      +

      View -> Display Branch Screenshots

      +

      Displays pop-up screenshots when you point mouse cursor over Bookmarks. The screenshot helps you to recall movie events saved to the Bookmark, which simplifies searching for the needed branch of the movie, as you don't have to actually load the Bookmark when you need to have an idea on its contents. This way you can also quickly compare results of several alternative approaches.

      +

      This option is enabled by default. If disabled, no screenshots will pop up on mouse hover.

      +

      It's recommended to have it enabled, unless you're annoyed with pop-up pictures partially obstructing the view on the Piano Roll.

      +


      +

      View -> Display Branch Descriptions

      +

      Displays pop-up descriptions when you point mouse cursor over Bookmarks. The text, as well as the screenshot, gives you additional information about the contents of the Bookmark, helping to decide whether this branch should be loaded or not.

      +

      The description text is taken from the Marker above the frame of that Bookmark. The Marker itself may be actually removed from the working movie long ago, but if the Bookmark was created while the Marked existed, then this Marker still exists in the branch of this Bookmark. And if you load this Bookmark, the Marker will reappear on its place.

      +

      So, when trying alternative strategies of playing through a large segment (e.g. whole level of the game), before saving every approach to a separate branch, you can make a name for the approach by setting a Marker at the Playback cursor position and typing a text message like "here I chose upper way" or just "upper way". After that, save a Bookmark on that frame. Then you can remove the Marker together with the Input of the old approach and create next approach by applying another strategy of playing the segment. When the new approach if finished and replayed, you can again create a Marker with a Note like "here I chose lower way" and save all that to another Bookmark. After that you can save the project and, say, close Taseditor. Next day you can easily recall all pros and cons of the two strategies you tried. Each Bookmark will show you the screenshot of the bookmarked frame and the text you wrote for that Bookmark. While it can be hard to distinguish the strategies by screenshots (since both approaches end at the same event of the game), but text descriptions will make them easy to recognize.

      +

      This option is enabled by default. If disabled, no descriptions will pop up on mouse hover.

      +

      It's recommended to have it enabled, unless you're annoyed with pop-up text fields.

      +


      +

      View -> Enable Hot Changes

      +

      Switches the Hot Changes feature on and off.

      +

      Enabled by default. If disabled, all buttonpress symbols will be displayed in a standard black color. Otherwise, each symbol will have its own level of "hotness", depending on how long ago the corresponding Piano Roll cell was edited. Recently modified buttonpresses are more hot, so they are displayed by more intense shade of red. As the hotness decreases, the symbol colors become darker (more cold) and finally turn into standard black.

      +


      +

      +


      +

      In total, Taseditor supports 15 shades of hotness + zeroth black color. When you change the state of an Input cell, it receives maximum hotness value (15), and all the previously edited cells cool down by 1. Thereby you only need a quick look at the Piano Roll to get an idea which edits were done just recently and which were done before, or long ago.

      +

      Also, with Hot Changes you can see which buttonpresses were recently removed – instead of an empty cell there will be a dash of the corresponding color. The dash also changes its color while cooling down, and after 15 levels it finally disappears.

      +

      The same dashes appear when you insert new frames in the movie.

      +

      It's recommended to enable this feature to increase the usability of Taseditor. In theory it should even increase your working speed, because this way you never have to recall which actions you did a minute ago. Of course even without Hot Changes you can always remind the sequence of last actions by reverting History (making several Ctrl + Z keypresses) and then returning the movie to normal state again (making as many Ctrl + Y keypresses). But in this case you will also truncate the Greenzone. So better just leave the Hot Changes enabled.

      +

      The only downside of this feature is that Hot Changes data will be stored in the History Log and in FM3 project file, thus increasing the amount of occupied memory.

      +


      +

      View -> Follow undo context

      +

      Scrolls the Piano Roll to relevant place every time you make an undo or redo. A purple pointer appears on the modified frame for a brief moment, thus drawing your attention to the movie changes.

      +

      This option is enabled by default. If disabled, the Piano Roll won't automatically scroll to the purple pointer.

      +

      It's recommended to have it enabled, in order to be able to backtrack undos. Usually, right after you revert an operation you want to make another edit on the same frame or nearby, so the autoscrolling is useful.

      +


      +

      View -> Follow Marker Note context

      +

      Scrolls the Piano Roll to relevant Marker when you start editing its Note. For example, when you click the upper edit field to start editing the Note of the Marker above the Playback cursor, Piano Roll jumps to that Marker, allowing you to see its context (neighbor Markers and Input). And when you click the lower edit field (a Note above the Selection cursor), Piano Roll scrolls to the Marker above the Selection. This way you can observe the surroundings of the relevant Marker while editing its Note.

      +

      This option is enabled by default. If disabled, the Piano Roll won't automatically scroll to the Markers.

      +

      It's recommended to have it enabled.

      +


      +

      And the View settings are over. During your future work you likely won't need to change these checkboxes.

      +

      +

      Now open the "Config" submenu. Options listed in this menu affect Taseditor workflow more significantly. You may need reconfiguring some of them more than once.

      +


      +

      Config -> Project file saving options

      +

      Opens the dialog window where you can configure the autosave function and select which aspects should be saved to FM3 files.

      +

      Taseditor has the feature of automatically saving current project to disk when user doesn't save it manually (Ctrl + S) for too long. Before Taseditor, TASers saved their movie to disk every time they saved a savestate. But Taseditor projects store much more data, and saving FM3 files can take several seconds, so it's not reasonable to resave them too often.

      +

      The default autosave period is 15 minutes. This means, if you've made some substantial changes to the project (e.g. you edited Input, and an asterisk appeared in the TAS Editor window caption), and then didn't save project for 15 minutes, Taseditor will remind you about that or just execute saving itself, depending on the state of the "silently" checkbox. If the checkbox is enabled, Taseditor silently saves the project to disk under the same filename. If it is disabled, Taseditor brings up the "Save As" dialog, where you can confirm the saving or cancel it. In the latter case Taseditor will wait another period of time until reminding you about the unsaved data.

      +

      The autosave function only works when current project already has a filename.

      +

      Maximum possible value of the period is 1440 minutes (24 hours). You can disable this function by switching off the "Autosave project" checkbox, but that's not recommended.

      +


      +

      Config -> Set max undo levels

      +

      Specifies the maximum number of undo steps, how many times you can restore previous state of the project by pressing Ctrl + Z.

      +

      The History Log needs a lot of computer memory and takes some disk space to save FM3 files. The whole Log is stored in project files in compressed state. The compression is done in background – when the emulator is idle, Taseditor gradually compresses new items of the History Log. Thanks to this behavior, the History Log size doesn't affect FM3 saving time much.

      +

      With this setting you can adjust the amount of memory occupied by History Log. By default you have 100 undo levels, which means you can revert up to hundred of recent movie edits. It's not very much, because during real TASing you make lots of various edits within a small time span, as the time runs imperceptibly. If your computer has enough RAM, you can increase the "max undo levels" value up to the maximum possible number – 1000.

      +


      +

      +

      Config -> Set Greenzone capacity

      +

      Defines the maximum size of the Greenzone. The Greenzone is used for easier Playback cursor navigation, allowing to instantly return to any frame that has been emulated. It needs a lot of computer memory to store emulator's information and a lot of disk space for saving FM3 projects.

      +

      The more of green and red frames there are in the Piano Roll, the more memory the Greenzone occupies. For most NES games 1 frame costs about 10 kilobytes (compressed data). So, big movie projects may take hundreds of megabytes. It affects the project loading and saving time.

      +

      To decrease the amount of needed memory, Taseditor regularly cleans the Greenzone tail, forgetting the info about segments that are too far from the Playback cursor.

      +

      This cleaning doesn't mean the Greenzone becomes inaccessible (white) on those frames. That would be very inconvenient, because to replay these frames you would need to wait until the emulation runs from the beginning of the movie. To avoid such inconvenience and still free some memory from old Greenzone sections, Taseditor uses gradual rarefication of the Greenzone tail.

      +

      This process works like shown on the picture to the right. The light-blue cursor runs down along the Piano Roll. The cursor is the head of the Greenzone. It leaves green/red lines behind, but far above it some of the lines become pale again. At first, every odd frame is cleared, then 3 of every 4, then 7 of 8, and finally 15 of 16.

      +

      Thus the Greenzone tail contains many hollow sections. And if you decide to send emulator to a frame inside such hollow section, you'll need to wait while emulation runs to it from the nearest bright Greenzone frame. But since bright frames alternate every 2 or 4 frames, the waiting will only last a split second, so you won't likely notice the difference between jumping to a regular Greenzone frame (instant jump) and jumping to a cleared tail (instant seeking).

      +

      By adjusting the "Set greenzone capacity" setting you can specify how many Greenzone frames (starting from its head) must stay untouched. On the picture to the right this number is 8.

      +

      For an experiment, choose the "Set greenzone capacity" item, a dialog window will appear asking you to enter a number, type 100 and press OK. This will mean that first hundred of frames above the Playback cursor should not be cleaned. Any cursor navigation along this area will be instant, so you may drag the light-blue cursor and use rewind with maximum comfort. After the first hundred of frames the cleaning will be removing every other frame – you'll see alternation of bright and pale lines in the Piano Roll. This alternation will last for about 200 frames. The Playback cursor navigation along the area of 200 frames will also be almost instant.

      +

      This way the Greenzone covers 100 + 200 = 300 frames, while only 100 + 100 = 200 frames are stored in memory. Then, during next 400 frames, every filled line will alternate with 3 cleared lines, and so on. In total, the Greenzone will only occupy memory needed for storing the data of 500 frames (about 5 MB), while the accessible area will be 3100 frames (about a minute).

      +

      By default, the Greenzone capacity is 10000 frames. This should be enough for most TASes. It's recommended to TAS with no less than 1000 frames of Greenzone capacity, because the further economy would be impractical.

      +

      The maximum number for that parameter is 50000.

      +


      +

      Config -> Enable Greenzoning

      +

      Controls the process of collecting data to the Greenzone.

      +

      If the option is enabled, every new frame is saved into the Greenzone right after it has been emulated. This is intended behavior of Taseditor, so the option is enabled by default.

      +

      Disabling this option may be useful in rare cases, for example, when running bots which need high performance. But in normal situations it's recommended to have this function enabled.

      +


      +

      Config -> Autofire Pattern skips Lag

      +

      Accounts for lag when you're using patterns (Alt + clicks on Input).

      +

      If the option is disabled, patterns appear in the Piano Roll exactly like they were coded (e.g. for the pattern "Alternating (1010...)" the new buttonpresses will indeed alternate one after another).

      +

      If the option is enabled, the resulting sequence of buttonpresses may differ from original pattern (lag frames will have additional gaps not present in the pattern).

      +

      Since lag frames aren't accounted by most games, you have to skip red lines of the Piano Roll to correctly calculate the gaps between presses. For instance, if there must be exactly 3 blank frames between every buttonpress (pattern "10001000"), but there's also one lag frame in the middle of current segment, you have to add 1 more blank frame  (100001000).

      +

      This option is enabled by default. It's recommended to leave it enabled, because in vast majority of cases you'll need to skip lag frames, in order to adapt buttonpresses to how the game interprets Input.

      +


      +

      Config -> Auto-adjust Input according to Lag

      +

      Enables automatic adjustment of Input according to changes of lag data.

      +

      Basically, games only care about Input at green lines of the Piano Roll. It's pointless to draw any Input on red lines, because during lag frames the game doesn't poll Input. Those frames simply don't exist from the point of view of the game engine.

      +

      When you edit Input, you change the flow of game events, and lag may appear on different frames too. If those frames previously had a meaningful Input, this Input must be shifted to the frames without lag, to allow it to affect the game.

      +

      If this checkbox is enabled, you won't have to adjust the Input manually every time the Lag appears on different frames. Taseditor will insert an extra line at every new lag frame, thus shifting Input 1 frame down. And when an old lag frame disappears, Taseditor will remove respective frames from the movie, thus shifting Input up. As a result, you can be sure that the game will always perceive your old Input correctly, no matter any Lag changes.

      +

      Auto-adjustment operations are done by Taseditor only when you're watching (emulating) a segment, i.e. when Playback cursor runs through pale Piano Roll lines. The result of these operations is saved into the current History Log item.

      +

      This feature is enabled by default, and it's recommended to always work with the function enabled. It significantly increases the comfort of TASing, especially when dealing with lag-heavy games.

      +


      +

      Config -> Draw Input by dragging

      +

      Allows to literally draw Input by holding the left mouse button and moving the mouse cursor over the Piano Roll.

      +

      This option is enabled by default, so you can quickly draw or erase a long line of buttonpresses.

      +

      Drawing/erasing is usually constrained by single column, which allows user to do sweeping motions with the mouse. But if you hold the Shift key while drawing, you will be able to draw/erase Input freely (it's rather impractical, but fun).

      +

      If you disable this option, your clicks will only set/unset single buttonpresses. It may be necessary, for example, if you have trembling hands. But otherwise enabling this feature is recommended.

      +


      +

      Config -> Combine consecutive Recordings/Draws

      +

      Combines consecutive operations of Input Recording into single item of the History Log. Also combines all Input drawn with the same press of mouse button.

      +

      This feature is disabled by default. So when you're recording Input, every recorded frame will create a separate item in the History Log, and you can undo changes for any frame. Also, when you're drawing Input, every new stroke will create a new History Log item, and you can undo each of them separately.

      +

      However, in real TASing you don't need such precision of the undo. In fact, it may even become irritating when you have to undo every buttonpress separately. So, to save considerable amount of space in History Log, it's recommended to enable this option.

      +


      +

      Config -> Use 1P keys for all single Recordings

      +

      Allows to record any joypad Input using only the first gamepad (1P). This function is used when you record Input traditional way using multitracking method to take turns for different players, e.g. first you record a short segment of Input for player one (1P), then record the Input for 2P and so on.

      +

      Thanks to multitracking, you don't have to press buttons on both controllers at once. And with the "Use 1P keys for all single Recordings" option you don't even have to configure 2P controls, because the same keys used for 1P can be used for all the rest joypads too.

      +

      The option is enabled by default. If you disable it, emulator will use the second controller keys for recording 2P.

      +

      It's recommended to have it enabled, in order to save the space on the keyboard.

      +


      +

      Config -> Use Input keys for Column Set

      +

      Allows editing Input in selected frames by pressing corresponding joypad keys.

      +

      This feature is intended to speed up the Input editing process. To mass-set/mass-unset buttonpresses in a given segment, you usually either draw with mouse, or select a range of frames and click the necessary symbol in the Piano Roll Header – the symbol flashes and the respective Input changes in all the selected frames.

      +

      With the "Use Input keys for Column Set" option you can press real keys (assigned to joypads) instead of clicking the Piano Roll Header. The result will be the same.

      +

      The option is disabled by default. Turn it on if you mostly use the new TASing methods and don't record Input traditional way. But when you're using Recording, either disable it or just remove the Selection to avoid Input changes on the selected frames when pressing joypad buttons.

      +

      With this feature you can record joypad buttons even when Recording is off. Put the Selection cursor to the frame you want to apply Input to, and press the needed joypad buttons.

      +

      Multitracking mode in this case works the same way as with regular Recording. For example, if the "2P" radiobutton is chosen at the moment, pressing the key assigned to the A button will only record Input for the "A" column of the 2nd player.

      +


      +

      Config -> Bind Markers to Input

      +

      Attaches Markers to Input. If the option is enabled, various Input editing functions will also affect Markers. For example, inserting blank frames into the movie will shift down both Input and Markers.

      +

      Usually Markers are set to frames where certain in-game events occur. And when you improve previous result and reach the given place earlier than before, the corresponding Marker (set there after previous attempt) should point to an earlier frame now. Sometimes you have to drag such Markers manually. But thanks to the binding feature, Markers will shift themselves during Input modifications, so the manual adjustment of Markers is rarely needed.

      +

      Detaching Markers may be necessary when you need to edit Input without shifting Markers. For example, when you need to remove a part of Input, leaving Markers intact.

      +

      The option is on by default. It's recommended to work with attached Markers most of the time, temporarily detaching them when necessary.

      +

      For clarification, Taseditor highlights attached Markers with a pale yellow color, and detached Markers with more bright yellow.

      +


      +

      Config -> Empty new Marker Notes

      +

      Defines the default Notes text. If the option is set, each newly created Marker will have an empty Note. If not set, the new Marker will copy the above Marker's Note text.

      +

      The option is enabled by default. It's recommended to left it on and type original Notes for important Markers, thus not leaving all Notes blank.

      +


      +

      Config -> Old control scheme for Branching

      +

      Imitates certain limitations of the traditional TASing method, particularly related to handling the Bookmarks (savestates).

      +

      The option is disabled by default, so hotkeys F1-F10 are used to load branch of the the corresponding Bookmarks, and the numeric keys 1-10 are used for simple jumps to bookmarked frames without changing the movie.

      +

      Also, Input Recording is switched on with a simple press of the Toggle Read-Only hotkey.

      +

      But if you enable this option, the controls scheme will be the same as in old emulators. Pressing F1-F10 will work depending on the Recording mode. When the Recording is off, functional keys jump to respective Bookmark frame, and when Recording is on, F1-F10 keys load the branch of the Bookmark.

      +

      Also, Input Recording won't work until you load some Bookmark. This behavior allows you to press the Toggle Read-Only hotkey in the middle of watching the movie, without overwriting old Input until you actually load a savestate.

      +

      Plus, there will be a red frame around the "current slot" number in the Bookmarks List. Press numeric keys 1-10 to switch the current slot.

      +

      This option is only left here to help old TASers move to Taseditor. But it's recommended to use the new controls scheme, because it fits the specifics of TASing process in Taseditor much better.

      +


      +

      Config -> Branches restore entire Movie

      +

      Defines the way a branch is restored when you load its Bookmark.

      +

      The option is enabled by default, so when you're loading a Bookmark, you replace the current movie with the movie state stored in that Bookmark.

      +

      If this option is disabled, when you're loading a Bookmark, the current movie is replaced with a truncated version of the bookmarked movie state. The movie will be truncated at the bookmarked frame, thus imitating the traditional behavior of loading a savestate: savestates only recover the part of the movie before the Playback cursor, and the rest frames (from the light-blue cursor to the movie end) aren't loaded. This makes sense when TASing traditional way, because after loading a savestate TASer usually records a new Input starting from the position of the Playback cursor, so there's no need to load the data that is going to be be overwritten anyway. But in Taseditor the movie is edited independently from the Playback cursor position, so you can load the entire movie state from Bookmarks, without caring if the Playback cursor is in the end of the movie or it is in the middle.

      +

      It's recommended to leave this option enabled.

      +


      +

      Config -> HUD in Branch screenshots

      +

      Defines the way to capture screenshots when creating Bookmarks.

      +

      If the option is on, it takes a snapshot of the whole emulator window, including icons and emulator messages, Lua output and other data placed over the game picture. If the option is disabled, Bookmarks will only capture the game output.

      +

      The option is enabled by default. It's recommended to leave it on, in order to use Lua output and frame counter when comparing alternate approaches to playing through a segment.

      +


      +

      Config -> Autopause at the end of Movie

      +

      Automatically stops movie playback at the last frame, unless it started playing from the last frame.

      +

      When replaying a finished (or partially finished) movie, you usually don't want to pass over the boundary of its Input. That's why the "Autopause at the end of Movie" option is enabled by default. If you disable it, the emulator will play infinitely after the current movie Input ended, expanding the movie size until you press Pause or the middle mouse button.

      +

      It's recommended to leave this option enabled.

      +


      +
      +


      +

      Now you are aware of all Taseditor settings, the remaining part of the chapter describes FCEUX emulator settings that may be useful for a TASer.

      +


      +

      If you are going to TAS traditional way, it's obligatory to set the first controller buttons to such keys that would be easy to press together with the Frame Advance hotkey. While FCEUX supports binding the virtual NES joypad to a real PC gamepad, it's recommended to use the keyboard for recording Input, in order to have fast access to Frame Advance, Frame Rewind, Pause, and to all 10 savestate slots.

      +

      However, if you use Taseditor as intended, you won't need to use Recording too much, and even in cases when you use it (for example, when recording a test playthrough of a level), an access to functional keys isn't critical. So, you can reassign the game controls to a USB gamepad, if you have one.

      +

      Virtual controller buttons are configured in FCEUX the following way. Choose Config -> Input in emulator main menu. In the appeared dialog, select the "Gamepad" item from the leftmost drop-down listbox (usually it's already selected). Click the left Configure button (since you need to configure the first gamepad). In the new window click the Up button, then a small window will appear, now press the keyboard key you want to set for the virtual Up button. Press that key 2nd time to confirms your choice, or just click Close. Then you need to do the same for the rest buttons of NES gamepad – Down, Left, Right, Select, Start, B, A. After you're done with the first controller buttons (Virtual Gamepad 1), you may close both windows: Gamepad and Input Configuration.

      +

      You can check the assigned buttons while playing the game or while Taseditor is engaged – as you press them, the corresponding symbols in the Piano Roll Header will shine with green color. Besides, if you enable Input display (FCEUX: Config -> Display -> Input Display -> 2 player), FCEUX screen will show you the pressed buttons too.

      +

      In addition to recording the regular gaming session, virtual gamepad buttons may be used to quickly set Input when editing movie (see Config -> Use Input keys for Column Set). Select a range of frames where you want to change Input and press the key you assigned to a button of the virtual gamepad.

      +

      When you map the virtual buttons to keyboard keys, make sure none of the emulator or Taseditor hotkeys are already assigned to those keys. The full list of default hotkeys can be found in the Reference.

      +

      Some FCEUX hotkeys don't have default mapping (they're not mapped to any key yet). You can configure them the following way. In the emulator main menu choose Config -> Map Hotkeys. A window listing all possible emulator hotkeys will appear. Choose the necessary hotkey, double-click it and then press the desired keyboard key.

      +

      First of all, find the item called "Open TAS Editor" and double-click it. In the appeared window press the key that you will always use to quickly launch Taseditor.

      +

      Second, find the item "Reload ROM or TAS Editor Project" and either remap it or remember the default combination (Ctrl + F1). This hotkey will help you quickly return to your interrupted work – just launch FCEUX, press the Reload ROM hotkey, then press the aforementioned Open TAS Editor hotkey, and then again Reload ROM (this time it will work as Reload TAS Editor Project). This way you'll return to the state of your paused work in a split second.

      +

      Now look at the hotkeys "Frame Advance" и "Frame Rewind". They are used for Playback cursor navigation. By default they are mapped to "\" and "Backspace". You can reconfigure them to more handy keys or just use the mouse wheel for the Playback cursor frame-by-frame navigation.

      +

      Also see the "Speed Down" and "Speed Up" hotkeys. You may consider remapping them to Numpad keys "+" and "-".

      +

      The "Pause" и "Restore Playback" hotkeys are set to "Pause/Break" and "Spacebar" keys by default, but in most cases it's easier to use the middle mouse button instead of these hotkeys, so you can even reassign the "Spacebar" for something else if you wish.

      +

      Finally, there is the "Cancel Seeking" hotkey ("Esc" key by default). Pressing it is the same as clicking the Taseditor progressbar – if the Playback was seeking to a target frame, the seeking will be aborted.

      +

      Some FCEUX hotkeys don't work when Taseditor is engaged. For example, the "Open ROM" won't work – you have to load ROM before running Taseditor. This is done for mistake-proofing.

      +


      +

      The next chapter describes additional features of Taseditor. You may postpone reading it until you are used to main features. Anyway, now you're ready enough for productive work in Taseditor.

      +


      +


      +


      +


      +


      -

      Created with the Personal Edition of HelpNDoc: Write EPub books for the iPad

      -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/ProgramInterface.html b/web/help/taseditor/ProgramInterface.html index 31d15178..56aac739 100644 --- a/web/help/taseditor/ProgramInterface.html +++ b/web/help/taseditor/ProgramInterface.html @@ -1,129 +1,326 @@ - - + + + + + - 2. Program Interface - - - - - - - - - - + + + + + + + + 2. Program Interface + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      2. Program Interface

      - -
      - Beginner's Guide ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      2. Program Interface

      + +
      +

      -

      Program Interface

      +

      Program Interface



      -

      This chapter describes the program interface and ways of interacting with it.

      -

      The description uses many specific terms, so make sure you know the Glossary before starting the read. Also, it's advisable to run Taseditor right now, to be able to check everything you read in practice.

      -


      -

      To enter Taseditor do the following:

      -
        -
      1. launch FCEUX emulator
      2. -
      3. load any game ROM (File -> Open ROM)
      4. -
      5. open Taseditor window (Tools -> TAS Editor)
      6. +

        This chapter describes the program interface and ways of interacting with it.

        +

        The description uses many specific terms, so make sure you know the Glossary before starting the read. Also, it's advisable to run Taseditor right now, to be able to check everything you read in practice.

        +


        +

        To enter Taseditor do the following:

        +
          +
        1. launch FCEUX emulator
        2. +
        3. load any game ROM (File -> Open ROM)
        4. +
        5. open Taseditor window (Tools -> TAS Editor)
        -


        -

        When you engage Taseditor, the game is reset, and the emulator pauses. It shall stay paused as you TAS, to prevent the game from urging you on and distracting from analysis of information.

        -


        -

        -


        -

        While TASing in Taseditor, a considerable part of the desktop is covered by the very Taseditor window. Emulator window is used for picture output, and you'd better scale it up to 2x size, so you won't miss a tiny detail even at a cursory glance. During your work you'll have to move eyes between emulator window and Taseditor window (mostly contents of the Piano Roll). So put those windows close to each other. The remaining space of the desktop can be populated with RAM Watch window, Lua console, etc.

        -


        -

        You can adjust the size of TAS Editor window by dragging its edges with the mouse. The size and position are automatically saved and restored at next launch.

        -


        -

        The window caption displays the program name ("TAS Editor") and the name of current project. If there are any unsaved changes, an asterisk is added to the end of the text. Besides, when the Input Recording mode is on, the word "Recording" appears in the window caption.

        -


        -

        The main menu of the program is similar to one found in text editors like Notepad.

        -

        The File item is responsible for all file operations – creating a new TAS project, opening an existing file, saving, data importing and exporting. There's also a "Recent" sub-menu that stores direct paths to recently used projects.

        -

        The Edit item contains functions that let you edit TAS movie like a simple text file or a table file. Most of those functions can be accessed through standard key combinations, such as Ctrl + C, Ctrl + V and others. They will be reviewed later.

        -

        The View item allows to adjust the program appearance. Besides, here you can open the "Find Note" window, used to search text in Marker Notes. All of that will be described later. Until you study the Chapter 5 of this Guide, it's recommended to keep default preferences.

        -

        The Config item stores the rest settings, e.g. project auto-saving timer, the number of undo levels and other features that will be described during the learning flow. Don't change those settings for now.

        -

        Finally, the Help item contains the link to local copy of this Guide and the "About" window. Here you can also switch on/off hints (tooltips).

        -

        To the right of the main menu there is the Pattern item, displaying the name of current pattern. Patterns are just templates for speeding up the Input creation. They will be described in Chapter 6.

        -


        -
        - - - - - -

        -
        - - - +


        +

        When you engage Taseditor, the game is reset, and the emulator pauses. It shall stay paused as you TAS, to prevent the game from urging you on and distracting from analysis of information.

        +


        +

        +


        +

        While TASing in Taseditor, a considerable part of the desktop is covered by the very Taseditor window. Emulator window is used for picture output, and you'd better scale it up to 2x size, so you won't miss a tiny detail even at a cursory glance. During your work you'll have to move eyes between emulator window and Taseditor window (mostly contents of the Piano Roll). So put those windows close to each other. The remaining space of the desktop can be populated with RAM Watch window, Lua console, etc.

        +


        +

        You can adjust the size of TAS Editor window by dragging its edges with the mouse. The size and position are automatically saved and restored at next launch.

        +


        +

        The window caption displays the program name ("TAS Editor") and the name of current project. If there are any unsaved changes, an asterisk is added to the end of the text. Besides, when the Input Recording mode is on, the word "Recording" appears in the window caption.

        +


        +

        The main menu of the program is similar to one found in text editors like Notepad.

        +

        The File item is responsible for all file operations – creating a new TAS project, opening an existing file, saving, data importing and exporting. There's also a "Recent" sub-menu that stores direct paths to recently used projects.

        +

        The Edit item contains functions that let you edit TAS movie like a simple text file or a table file. Most of those functions can be accessed through standard key combinations, such as Ctrl + C, Ctrl + V and others. They will be reviewed later.

        +

        The View item allows to adjust the program appearance. Besides, here you can open the "Find Note" window, used to search text in Marker Notes. All of that will be described later. Until you study the Chapter 5 of this Guide, it's recommended to keep default preferences.

        +

        The Config item stores the rest settings, e.g. project auto-saving timer, the number of undo levels and other features that will be described during the learning flow. Don't change those settings for now.

        +

        Finally, the Help item contains the link to local copy of this Guide and the "About" window. Here you can also switch on/off hints (tooltips).

        +

        To the right of the main menu there is the Pattern item, displaying the name of current pattern. Patterns are just templates for speeding up the Input creation. They will be described in Chapter 6.

        +


        +
        +

        Contents of the TAS Editor window can be divided into 2 parts – the workspace (Piano Roll) to the left and the Toolbox to the right.

        -


        -

        Proceed to the Piano Roll description

        -


        -


        -
        + + + + +
        +

        +
        +
        + + + + +
        +

        Contents of the TAS Editor window can be divided into 2 parts – the workspace (Piano Roll) to the left and the Toolbox to the right.

        +


        +

        Proceed to the Piano Roll description

        +


        +


        +
        +
        +


        +


        +
        +

        +
        -


        -


        -

        -
        -
        -


        -


        -


        -


        +


        +


        +


        +


        -

        Created with the Personal Edition of HelpNDoc: Free PDF documentation generator

        -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/Reference.html b/web/help/taseditor/Reference.html index 70abac1e..4320dc16 100644 --- a/web/help/taseditor/Reference.html +++ b/web/help/taseditor/Reference.html @@ -1,95 +1,290 @@ - - + + + + + - Reference - - - - - - - - - - + + + + + + + + Reference + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Reference

      - -
      -
      - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Reference

      + +
      +

      -

      Reference

      +

      Reference



      -

      Glossary

      -

      Terms that are used throughout this documentation

      -


      -

      Controls

      -

      Exhaustive review of controls

      -


      -

      Navigation

      -

      The summary of all ways to navigate a movie

      -


      -

      Operations

      -

      The list and mini-reviews of all possible operations with a movie

      -


      -

      Lua API

      -

      Specifications of "taseditor" library of Lua functions

      -


      -

      FAQ

      -

      Answers to some expected questions

      -


      -

      Speedrunning synopsis

      -

      Abstract classification of typical issues arising when optimizing a segment for fastest time

      -


      -


      -


      -


      -


      +

      Glossary

      +

      Terms that are used throughout this documentation

      +


      +

      Controls

      +

      Exhaustive review of controls

      +


      +

      Navigation

      +

      The summary of all ways to navigate a movie

      +


      +

      Operations

      +

      The list and mini-reviews of all possible operations with a movie

      +


      +

      Lua API

      +

      Specifications of "taseditor" library of Lua functions

      +


      +

      FAQ

      +

      Answers to some expected questions

      +


      +

      Speedrunning synopsis

      +

      Abstract classification of typical issues arising when optimizing a segment for fastest time

      +


      +


      +


      +


      +


      -

      Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle

      -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/SemiautomaticTASing.html b/web/help/taseditor/SemiautomaticTASing.html index 73a8beaa..c2eee437 100644 --- a/web/help/taseditor/SemiautomaticTASing.html +++ b/web/help/taseditor/SemiautomaticTASing.html @@ -1,168 +1,359 @@ - - + + + + + - 4.3. Semiautomatic TASing - - - - - - - - - - + + + + + + + + 4.3. Semiautomatic TASing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      4.3. Semiautomatic TASing

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      4.3. Semiautomatic TASing

      + +
      +

      -

      Semiautomatic TASing

      -


      -


      -

      -

      This method further develops the ideas of the nonlinear TASing method.

      -

      In many cases TASer needs to see the result of the Input modification immediately. Ideally, he should realize all the consequences of his decision right at the moment of making the decision. But in reality he has to spend precious time on inputting the decision and navigating with the Playback cursor to the end of the segment.

      -

      In these cases you can leave the Playback navigation to Taseditor and just focus on editing. Taseditor will immediately react on any Input modification and display the new result.by bringing the Playback cursor to the end of the current segment.

      -

      When you feel the influence of every click, you build very high level of interconnection between TASer and the game. In such close interaction both TASer controls the game and the game urges TASer's actions into right direction. Of course, such high level of interdependency is not always useful, because it narrows your spectrum of thoughts, not allowing to look down on the game and apply a logic from different games and other fields of life.

      -

      However, when the current segment is simple and all optimality factors are already known (and you only need to find the perfect combination of them), it's useful to abstract from everything else and devote full attention to going over the possible options. This way you can test a lot of approaches before you become bored with the current segment.

      -

      The Recording mode should be off. The "Auto-restore last position" checkbox should be on. The "Turbo seek" and "Follow cursor" checkboxes are usually disabled, but may be enabled when necessary.

      -


      -

      General activity:

      -


      -
        -
      1. Scroll the Piano Roll to the beginning of the edited segment, put the Playback cursor here, define the goal.
      2. -
      3. Detect the end of the segment and leave the Playback cursor there.
      4. -
      5. Suppose there's a mistake in the segment, weigh known factors of optimality and figure out the way to fix the mistake.
      6. -
      7. The mouse cursor navigation to any frame of the current segment is practically instant.
      8. -
      9. Edit the segment with the mouse. After every Input modification the Playback cursor will automatically replay the segment and stop at the frame that was considered to be the end of the segment. If necessary, you can shift the end of the segment by moving the Playback cursor manually (e.g. using the mouse wheel). The steps 4 and 5 are constantly alternating until you consider the editing complete, according to the optimality criterion.
      10. -
      11. [optional step] Save the finished approach to any free Bookmark, e.g. to slot 8 or 7.
      12. -
      13. If this isn't the first approach to the segment, compare the new result to the best old result, using the optimality criterion. If the new approach is better (or it's the first approach), save the result to the Bookmark 9. The slot 9 will be used for keeping the best result of polishing the segment.
      14. -
      15. If you still want to try different series of approaches, return to step 3, until you run out of ideas.
      16. -
      17. [optional step] If you need more ideas, you can get some information from the past or the future by moving the Playback cursor to different segments of the movie or unpausing the emulator. When necessary, you can quickly draw a rough Input for watching the upcoming events of the game. But when returning to the segment modification you have to return the Playback cursor to the frame of the target event.
      18. -
      19. When there's no more ideas, restore the best approach from the History Log or the Bookmark 9 into the current movie and proceed to the next segment.
      20. +

        Semiautomatic TASing

        +


        +


        +

        +

        This method further develops the ideas of the nonlinear TASing method.

        +

        In many cases TASer needs to see the result of the Input modification immediately. Ideally, he should realize all the consequences of his decision right at the moment of making the decision. But in reality he has to spend precious time on inputting the decision and navigating with the Playback cursor to the end of the segment.

        +

        In these cases you can leave the Playback navigation to Taseditor and just focus on editing. Taseditor will immediately react on any Input modification and display the new result.by bringing the Playback cursor to the end of the current segment.

        +

        When you feel the influence of every click, you build very high level of interconnection between TASer and the game. In such close interaction both TASer controls the game and the game urges TASer's actions into right direction. Of course, such high level of interdependency is not always useful, because it narrows your spectrum of thoughts, not allowing to look down on the game and apply a logic from different games and other fields of life.

        +

        However, when the current segment is simple and all optimality factors are already known (and you only need to find the perfect combination of them), it's useful to abstract from everything else and devote full attention to going over the possible options. This way you can test a lot of approaches before you become bored with the current segment.

        +

        The Recording mode should be off. The "Auto-restore last position" checkbox should be on. The "Turbo seek" and "Follow cursor" checkboxes are usually disabled, but may be enabled when necessary.

        +


        +

        General activity:

        +


        +
          +
        1. Scroll the Piano Roll to the beginning of the edited segment, put the Playback cursor here, define the goal.
        2. +
        3. Detect the end of the segment and leave the Playback cursor there.
        4. +
        5. Suppose there's a mistake in the segment, weigh known factors of optimality and figure out the way to fix the mistake.
        6. +
        7. The mouse cursor navigation to any frame of the current segment is practically instant.
        8. +
        9. Edit the segment with the mouse. After every Input modification the Playback cursor will automatically replay the segment and stop at the frame that was considered to be the end of the segment. If necessary, you can shift the end of the segment by moving the Playback cursor manually (e.g. using the mouse wheel). The steps 4 and 5 are constantly alternating until you consider the editing complete, according to the optimality criterion.
        10. +
        11. [optional step] Save the finished approach to any free Bookmark, e.g. to slot 8 or 7.
        12. +
        13. If this isn't the first approach to the segment, compare the new result to the best old result, using the optimality criterion. If the new approach is better (or it's the first approach), save the result to the Bookmark 9. The slot 9 will be used for keeping the best result of polishing the segment.
        14. +
        15. If you still want to try different series of approaches, return to step 3, until you run out of ideas.
        16. +
        17. [optional step] If you need more ideas, you can get some information from the past or the future by moving the Playback cursor to different segments of the movie or unpausing the emulator. When necessary, you can quickly draw a rough Input for watching the upcoming events of the game. But when returning to the segment modification you have to return the Playback cursor to the frame of the target event.
        18. +
        19. When there's no more ideas, restore the best approach from the History Log or the Bookmark 9 into the current movie and proceed to the next segment.
        -


        -
        -


        -

        The main difference between this and previous method is that here the Playback cursor is generally located at the end of the current segment, and not at the beginning. Every time the Greenzone truncates, the Playback cursor seeks to the end of the segment, or rather to the frame where the segment end was before you modified the Input. If the Input modification also changed the frame of the target event, you can additionally move the light-blue cursor by mouse wheel if needed. But often there's no need for precise positioning, because you may only need to know the sequence of events occurring in the segment due to the Input modification.

        -

        The replay of the current segment is automatically launched after every interim step of the Input modifications, even when you haven't finished the thought yet and are not ready to compare the current result to the result of the previous approach. Fortunately, when TASer is carried away by the editing process, he doesn't look at FCEUX screen and only clicks the Piano Roll, until his idea is implemented in the form of a full-fledged button combination. And when the Input is starting to become interesting, TASer pays attention to the emulator screen or the Memory Watch window.

        -

        For example, when you need to create a jump over a pit, you first draw a long row of the R button presses, and you don't care that at the same time the FCEUX screen displays how Mario runs and falls into the pit. You just draw some A buttonpresses, then look at the emulator window and erase or draw additional A buttonpresses, thus changing the beginning and the duration of the jump while watching the trajectory of Mario sprite.

        -

        So, the process of polishing the Input in this method is a simultaneous editing and watching the segment. TASer gets in close informational contact with the game and soon starts to think synchronously with its responses. The game starts to help you filter and accept decisions. As a result, you may lose impartiality of your mind and stick to obvious decisions encouraged by the game. That's why you shouldn't use this method all the time, it's recommended to alternate it with the previous one.

        -


        -

        Like with the simple nonlinear method, you can change the speed of emulation and get different variations of the semiautomatic method:

        -
          -
        1. editing and watching the changes in real time
        2. -
        3. editing and watching the changes in slow motion
        4. -
        5. editing and instantly seeing the final result (turbo)
        6. +


          +
          +


          +

          The main difference between this and previous method is that here the Playback cursor is generally located at the end of the current segment, and not at the beginning. Every time the Greenzone truncates, the Playback cursor seeks to the end of the segment, or rather to the frame where the segment end was before you modified the Input. If the Input modification also changed the frame of the target event, you can additionally move the light-blue cursor by mouse wheel if needed. But often there's no need for precise positioning, because you may only need to know the sequence of events occurring in the segment due to the Input modification.

          +

          The replay of the current segment is automatically launched after every interim step of the Input modifications, even when you haven't finished the thought yet and are not ready to compare the current result to the result of the previous approach. Fortunately, when TASer is carried away by the editing process, he doesn't look at FCEUX screen and only clicks the Piano Roll, until his idea is implemented in the form of a full-fledged button combination. And when the Input is starting to become interesting, TASer pays attention to the emulator screen or the Memory Watch window.

          +

          For example, when you need to create a jump over a pit, you first draw a long row of the R button presses, and you don't care that at the same time the FCEUX screen displays how Mario runs and falls into the pit. You just draw some A buttonpresses, then look at the emulator window and erase or draw additional A buttonpresses, thus changing the beginning and the duration of the jump while watching the trajectory of Mario sprite.

          +

          So, the process of polishing the Input in this method is a simultaneous editing and watching the segment. TASer gets in close informational contact with the game and soon starts to think synchronously with its responses. The game starts to help you filter and accept decisions. As a result, you may lose impartiality of your mind and stick to obvious decisions encouraged by the game. That's why you shouldn't use this method all the time, it's recommended to alternate it with the previous one.

          +


          +

          Like with the simple nonlinear method, you can change the speed of emulation and get different variations of the semiautomatic method:

          +
            +
          1. editing and watching the changes in real time
          2. +
          3. editing and watching the changes in slow motion
          4. +
          5. editing and instantly seeing the final result (turbo)
          -

          -

          -

          Turbo-seeking creates an association between two distant events (the beginning and the end of the segment). Here the association is even more efficient, because there's even less intermediaries – the seeking starts before you even release the mouse button when drawing the Input. So you see the distant result almost at the same time you change the decisive Input, even if the game normally only shows the result in a several seconds.

          -

          -A good example would be the process of searching for the first possible frame of pressing the Start button. Some games actually allow to press the button before there's even any graphics on screen. Besides, after the Start button is activated, games often meditate for some time, not giving you any information if the button worked or not. Only after a second or two you can see the changes in the scenery, thus learning the buttonpress was successful.

          -

          In the traditional method of TASing you would need to spend 5-10 minutes on examination of approaches (searching for the very first frame), but the semiautomatic method allows to go over all the approaches much faster:

          -
            -
          • Switch on the "Auto-restore last position" and "Turbo seek" checkboxes. Switch off the "Follow cursor" checkbox.
          • +


            +

            Turbo-seeking creates an association between two distant events (the beginning and the end of the segment). Here the association is even more efficient, because there's even less intermediaries – the seeking starts before you even release the mouse button when drawing the Input. So you see the distant result almost at the same time you change the decisive Input, even if the game normally only shows the result in a several seconds.

            +

            A good example would be the process of searching for the first possible frame of pressing the Start button. Some games actually allow to press the button before there's even any graphics on screen. Besides, after the Start button is activated, games often meditate for some time, not giving you any information if the button worked or not. Only after a second or two you can see the changes in the scenery, thus learning the buttonpress was successful.

            +

            In the traditional method of TASing you would need to spend 5-10 minutes on examination of approaches (searching for the very first frame), but the semiautomatic method allows to go over all the approaches much faster:

            +
              +
            • Switch on the "Auto-restore last position" and "Turbo seek" checkboxes. Switch off the "Follow cursor" checkbox.
            -
              -
            • Set a trial Start button press at the frame where it definitely works, e.g. at the frame 100.
            • +
                +
              • Set a trial Start button press at the frame where it definitely works, e.g. at the frame 100.
              -
                -
              • Watch the game up to the frame where you can already tell by the picture that the Start was successful (e.g. the screen changed to "World 1-1" text). For example, it's the frame 150. Leave the Playback cursor at this frame – this will be the end of the segment.
              • -
              • Now remove the trial buttonpress (the FCEUX window will flash and the "World 1-1" will disappear, leaving only the title screen, since there's no more Start button press).
              • -
              • Set the Start buttonpress to the beginning of the segment, which is the place where you know it's too early for the buttonpress to be registered. For example, set it to the first frame of the movie. The image in the FCEUX window will flash but then still show the title screen, because the Start didn't work.
              • -
              • Hold Ctrl + Shift by one hand and begin pressing Insert key once per a second or so (that really depends on your computer performance). After every Ctrl + Shift + Insert combination the Start buttonpress moves one frame forward, and the FCEUX window shows you if the buttonpress changed the state of the game at frame 150 or not.
              • -
              • Until the Start doesn't reach the moment when the game is ready to accept the Input, the FCEUX window will show you the title screen. But when another press of Ctrl + Shift + Insert moves the Start to a suitable frame, the emulator will display the "World 1-1" screen.
              • -
              • This way you've found the very first frame to press the Start button. Most likely the frame number will be much less than 100.
              • +
                  +
                • Watch the game up to the frame where you can already tell by the picture that the Start was successful (e.g. the screen changed to "World 1-1" text). For example, it's the frame 150. Leave the Playback cursor at this frame – this will be the end of the segment.
                • +
                • Now remove the trial buttonpress (the FCEUX window will flash and the "World 1-1" will disappear, leaving only the title screen, since there's no more Start button press).
                • +
                • Set the Start buttonpress to the beginning of the segment, which is the place where you know it's too early for the buttonpress to be registered. For example, set it to the first frame of the movie. The image in the FCEUX window will flash but then still show the title screen, because the Start didn't work.
                • +
                • Hold Ctrl + Shift by one hand and begin pressing Insert key once per a second or so (that really depends on your computer performance). After every Ctrl + Shift + Insert combination the Start buttonpress moves one frame forward, and the FCEUX window shows you if the buttonpress changed the state of the game at frame 150 or not.
                • +
                • Until the Start doesn't reach the moment when the game is ready to accept the Input, the FCEUX window will show you the title screen. But when another press of Ctrl + Shift + Insert moves the Start to a suitable frame, the emulator will display the "World 1-1" screen.
                • +
                • This way you've found the very first frame to press the Start button. Most likely the frame number will be much less than 100.
                -


                -

                In the same way you can search for an optimal duration of holding the A button, trying to land at certain point. Also consider using this method for quick luck manipulation in many games. The automatic turbo-seeking works best when you deal with a single factor of optimality and need to quickly test a hundred of similar approaches.

                -

                In general, the semiautomatic method induces you to think less and experiment more. Sure, many videogames allow this way of solving tasks, but TASing requires more from you, so try not to take a fancy to the comfort of this method.

                -


                -
                -


                -

                Pros of the method:

                -

                + Instant navigation and high speed of the working process incites to conduct more tests.

                -

                + Constant feedback allows to adapt to the game while editing the Input, adjust your decisions and discard incorrect approaches prematurely.

                -

                + Possibility to skip useless scenes.

                -


                -

                Cons of the method:

                -

                The insistent game feedback provokes TASer to discard some illogical but potentially advantageous approaches.

                -

                Emphasis on the mouse controls.

                -


                -

                When the method is recommended to use: when you need to polish the segment already knowing all of its optimality factors. E.g. for quick resyncing of the old Input this method is better than previous. Also it may be better for making an initial playthrough of a segment.

                -


                -
                -


                -

                Now that you know the main principles of working in Taseditor, you can begin TASing your game of interest. Practice is the best teacher, so you'll only learn all intricacies of the activity by engaging in a real development of your own TAS.

                -

                After several weeks of practical TASing it's recommended to reread the 3rd and 4th chapters of this Guide, in order to understand the text on a deeper level.

                -


                -

                In the next chapter: tweaking the program.

                -


                -
                - - - +


                +

                In the same way you can search for an optimal duration of holding the A button, trying to land at certain point. Also consider using this method for quick luck manipulation in many games. The automatic turbo-seeking works best when you deal with a single factor of optimality and need to quickly test a hundred of similar approaches.

                +

                In general, the semiautomatic method induces you to think less and experiment more. Sure, many videogames allow this way of solving tasks, but TASing requires more from you, so try not to take a fancy to the comfort of this method.

                +


                +
                +


                +

                Pros of the method:

                +

                + Instant navigation and high speed of the working process incites to conduct more tests.

                +

                + Constant feedback allows to adapt to the game while editing the Input, adjust your decisions and discard incorrect approaches prematurely.

                +

                + Possibility to skip useless scenes.

                +


                +

                Cons of the method:

                +

                The insistent game feedback provokes TASer to discard some illogical but potentially advantageous approaches.

                +

                Emphasis on the mouse controls.

                +


                +

                When the method is recommended to use: when you need to polish the segment already knowing all of its optimality factors. E.g. for quick resyncing of the old Input this method is better than previous. Also it may be better for making an initial playthrough of a segment.

                +


                +
                +


                +

                Now that you know the main principles of working in Taseditor, you can begin TASing your game of interest. Practice is the best teacher, so you'll only learn all intricacies of the activity by engaging in a real development of your own TAS.

                +

                After several weeks of practical TASing it's recommended to reread the 3rd and 4th chapters of this Guide, in order to understand the text on a deeper level.

                +


                +

                In the next chapter: tweaking the program.

                +


                +
                +

                PRACTICE: Thoroughly polish the Input in the segments of your test movie. If the initial dividing appears to be wrong – just redo it on the fly.

                -

                Use only the 2nd and the 3rd method of TASing, because traditional method is obsolete. Also try using turbo when suitable.

                -

                Estimated time: 30-60 minutes.

                -
                + + +
                +

                PRACTICE: Thoroughly polish the Input in the segments of your test movie. If the initial dividing appears to be wrong – just redo it on the fly.

                +

                Use only the 2nd and the 3rd method of TASing, because traditional method is obsolete. Also try using turbo when suitable.

                +

                Estimated time: 30-60 minutes.

                +
                -


                -


                -


                -


                -


                +


                +


                +


                +


                +


                -

                Created with the Personal Edition of HelpNDoc: Produce Kindle eBooks easily

                -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/SpeedrunningSynopsis.html b/web/help/taseditor/SpeedrunningSynopsis.html index bc0e344e..284eb8aa 100644 --- a/web/help/taseditor/SpeedrunningSynopsis.html +++ b/web/help/taseditor/SpeedrunningSynopsis.html @@ -1,167 +1,347 @@ - - + + + + + - Speedrunning synopsis - - - - - - - - - - + + + + + + + + Speedrunning synopsis + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Speedrunning synopsis

      - -
      - Reference ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Speedrunning synopsis

      + +
      +

      -

      Speedrunning synopsis

      +

      Speedrunning synopsis



      -

      Thanks to having a definite goal, creating tool-assisted speedruns is the easiest application of TASing, and all relevant techniques are examined pretty well. Here you can find the summary of generic tasks emerging in the process of polishing the Input for a speedrun. Before reading this, make sure you've learned the materials in TASing Process and TASing Methodology.

      -


      -

      Speedrunners have to search for the shortest way of completing every segment of the game. This process of searching consists of testing a multitude of approaches for playing the segment and finally choosing the best approach. Here we will discuss only the problem of choice.

      -

      To simplify the problem, TASers usually compare only two approaches: the new working approach and the old best approach; all other old approaches are promptly forgotten (although the interesting ones can always be saved in the Bookmarks).

      -


      -

      The best of all old (previously tested) approaches can be stored:

      -
        -
      • in Bookmarks – recommended
      • -
      • in the History Log – automatically but temporary
      • -
      • in TASer's own memory – not recommended
      • +

        Thanks to having a definite goal, creating tool-assisted speedruns is the easiest application of TASing, and all relevant techniques are examined pretty well. Here you can find the summary of generic tasks emerging in the process of polishing the Input for a speedrun. Before reading this, make sure you've learned the materials in TASing Process and TASing Methodology.

        +


        +

        Speedrunners have to search for the shortest way of completing every segment of the game. This process of searching consists of testing a multitude of approaches for playing the segment and finally choosing the best approach. Here we will discuss only the problem of choice.

        +

        To simplify the problem, TASers usually compare only two approaches: the new working approach and the old best approach; all other old approaches are promptly forgotten (although the interesting ones can always be saved in the Bookmarks).

        +


        +

        The best of all old (previously tested) approaches can be stored:

        +
          +
        • in Bookmarks – recommended
        • +
        • in the History Log – automatically but temporary
        • +
        • in TASer's own memory – not recommended
        -


        -

        When the new working approach is considered to be better (more optimal) than the old best approach, it's naturally assumed that it's also better than any of the old approaches, so this working approach instantly becomes the best. In the case of using Bookmarks you should re-save the new approach to the slot where the old best approach was stored. At the end of the search the contents of this Bookmark slot are loaded into the final movie.

        -


        -

        Optimality criteria in speedruns:

        -
          -
        • presence/absence of the specific event in the new and old approach (bool)
        • -
        • the time of occurrence of the target event in the new and old approach (int)
        • -
        • the state of the game at the same frame in the new and old movie (string)
        • +


          +

          When the new working approach is considered to be better (more optimal) than the old best approach, it's naturally assumed that it's also better than any of the old approaches, so this working approach instantly becomes the best. In the case of using Bookmarks you should re-save the new approach to the slot where the old best approach was stored. At the end of the search the contents of this Bookmark slot are loaded into the final movie.

          +


          +

          Optimality criteria in speedruns:

          +
            +
          • presence/absence of the specific event in the new and old approach (bool)
          • +
          • the time of occurrence of the target event in the new and old approach (int)
          • +
          • the state of the game at the same frame in the new and old movie (string)
          -


          -

          Respectively, when you're comparing any pair of approaches you are doing one of the three possible actions:

          -

          1. Comparing presence/absence of the event.

          -

          A. By memory

          -

          B. Using Bookmarks

          -

          2. Comparing the time of occurrence.

          -

          A. By memory

          -

          B. Using the green arrow

          -

          C. Using a Marker

          -

          D. Using Bookmarks

          -

          3. Comparing the state of the game at one and the same frame.

          -

          A. By memory

          -

          B. Using Bookmarks

          -


          -

          -

          -

          1. Comparing presence/absence of the event.

          -

          Choose the approach where the needed event happens / unneeded event doesn't happen. The occurrence of the event is only the first (and often easy) step in creating the Input for current segment, and next step is to try speeding up the time of the occurrence.

          -

          The search for approaches goes on until the first successful approach is found, or until you're tired (then the event is considered to be unfeasible).

          -

          Programming analogy: comparing two Booleans, comparing  two arrays of Booleans.

          -


          -

          -A. Most of time it's enough to simply keep in mind the fact that target event didn't occur in previous approaches. Example: finding the Start buttonpress.

          -


          -

          -B. When the target event is complex (e.g. you plan to shoot 3 enemies simultaneously), it's recommended to save the most promising approaches into Bookmarks (e.g. an approach where you shot 2 enemies simultaneously and 3rd one shortly after), because if the target event is unfeasible, you might be satisfied with such partial success.

          -


          -

          -

          -

          2. Comparing the time of occurrence.

          -

          Choose the approach where the target event occurs earlier. The time of occurrence is defined by the frame in which the event can be detected, while in previous frame it cannot be detected. The number of this frame is found by bringing the Playback cursor to the frame and watching the FCEUX screen (or Memory Watch) for confirming.

          -

          The search for approaches goes on until you're tired, or until all possible types of approaches are exhausted (then the current best approach is considered to be frame perfect, until new factors are found).

          -

          Programming analogy: comparing two Integer Numbers.

          -


          -

          -A. For simplest segments and small subsegments it may be enough to just keep in mind the current fastest frame number and compare results of all new approaches with this number. But in general it's not recommended to rely on human memory. Details: TASing Process.

          -


          -

          -B. On simple segments you can refer to the green arrow of Taseditor. When using it, you're supposed to always leave the Playback cursor at the frame of target event (which is only natural). Thus if the new frame of target event is located above the green arrow, it means the new approach is faster than previous approach. Details:TASing Methodology.

          -


          -

          -C. On complex segments use an unbound Marker that always points at the current fastest frame number in the Piano Roll. Every time you beat the old result you're supposed to manually move the Marker higher. Thus if the new frame of target event is located above the Marker, it means the new approach is faster than the old best approach.

          -


          -

          -D. On segments of any level of complexity it's recommended to use Bookmarks that are displayed in the icons column of the Piano Roll. Every time you beat the old result you're supposed to manually save the current approach to the same Bookmark slot, replacing the old best approach stored there. Thus if the new frame of target event is located above the Bookmark icon, it means the new approach is faster than the old best approach.

          -


          -

          -

          -

          3. Comparing the state of the game at the same frame.

          -

          Choose the approach where properties of the game are more advantageous in a whole. This type of comparison is useful when you need to evaluate compound in-game situations. For example, in Formula 1 racing you have to care both about being as fast as possible and wearing tyres as little as possible, so you need to find an optimal balance on each segment of the track instead of simply rushing.

          -

          Here our segment has defined end frame, and every new test is supposed to replay the segment up to that frame. Taseditor stores this frame number in the form of the green arrow, which automatically pauses emulation when you watch new approaches. So TASer only needs to edit Input (creating new approaches), launch replaying, wait for the stopping and evaluate the result (judging by FCEUX screen or Memory Watch).

          -

          The search of approaches goes on until you're tired, or until all possible types of approaches are exhausted (then the current best approach is considered to be perfect, until new factors are found).

          -

          Programming analogy: comparing two Strings, comparing  two arrays of Integer Numbers.

          -


          -

          -A. For simple segments it may be enough to just keep in mind the value of the most important property of the game state achieved in the old best approach. Every time you watch the replaying of a new approach, you can compare results of the new approach with this value. If you decide the new value is better, you have to memorize it in place of old value. Example: luck manipulation.

          -

          When there's more than one important property, it's not recommended to rely on human memory.

          -


          -

          -B. On complex segments and especially on gigantic segments (e.g. with the size of a whole level of the game) use Bookmarks that store alternative branches of the movie. The best approach for playing the segment is saved into one Bookmark slot and the new approach is saved into another slot. Then you can easily switch between these slots and compare values of each property of the game state. In addition, you can point the mouse cursor to respective Bookmarks to see screenshots of the game state and visually compare their properties with current image on FCEUX screen.

          -

          To display important RAM data on screenshots you should use Lua graphical output, then Memory Watch window won't be required to judge about hidden properties, and you will be able to successfully judge by screenshots only. Details: Program Customization.

          -

          In the situation when some properties in the new approach are better and some others are worse you'll have to thoroughly weigh all of them (either in your mind or using a Lua-powered aggregate formula) and then decide which state of the game is better.

          -

          Every time you beat the old result you're supposed to manually save the new approach to the same Bookmark slot, replacing the old best approach stored there.

          -


          -
          -


          -

          After finding the fastest approach of playing the segment, a good TASer is expected to improve the entertainment value of the play through the segment. The optimality criteria in such activity may be very diverse, but the general requirement is to keep the same time of playing through the segment.

          -

          Alternatively, you can postpone the entertainment improvement of the segment and proceed to the next.

          -


          -


          -


          -


          -


          +


          +

          Respectively, when you're comparing any pair of approaches you are doing one of the three possible actions:

          +

          1. Comparing presence/absence of the event.

          +

          A. By memory

          +

          B. Using Bookmarks

          +

          2. Comparing the time of occurrence.

          +

          A. By memory

          +

          B. Using the green arrow

          +

          C. Using a Marker

          +

          D. Using Bookmarks

          +

          3. Comparing the state of the game at one and the same frame.

          +

          A. By memory

          +

          B. Using Bookmarks

          +


          +


          +

          1. Comparing presence/absence of the event.

          +

          Choose the approach where the needed event happens / unneeded event doesn't happen. The occurrence of the event is only the first (and often easy) step in creating the Input for current segment, and next step is to try speeding up the time of the occurrence.

          +

          The search for approaches goes on until the first successful approach is found, or until you're tired (then the event is considered to be unfeasible).

          +

          Programming analogy: comparing two Booleans, comparing  two arrays of Booleans.

          +


          +

          A. Most of time it's enough to simply keep in mind the fact that target event didn't occur in previous approaches. Example: finding the Start buttonpress.

          +


          +

          B. When the target event is complex (e.g. you plan to shoot 3 enemies simultaneously), it's recommended to save the most promising approaches into Bookmarks (e.g. an approach where you shot 2 enemies simultaneously and 3rd one shortly after), because if the target event is unfeasible, you might be satisfied with such partial success.

          +


          +


          +

          2. Comparing the time of occurrence.

          +

          Choose the approach where the target event occurs earlier. The time of occurrence is defined by the frame in which the event can be detected, while in previous frame it cannot be detected. The number of this frame is found by bringing the Playback cursor to the frame and watching the FCEUX screen (or Memory Watch) for confirming.

          +

          The search for approaches goes on until you're tired, or until all possible types of approaches are exhausted (then the current best approach is considered to be frame perfect, until new factors are found).

          +

          Programming analogy: comparing two Integer Numbers.

          +


          +

          A. For simplest segments and small subsegments it may be enough to just keep in mind the current fastest frame number and compare results of all new approaches with this number. But in general it's not recommended to rely on human memory. Details: TASing Process.

          +


          +

          B. On simple segments you can refer to the green arrow of Taseditor. When using it, you're supposed to always leave the Playback cursor at the frame of target event (which is only natural). Thus if the new frame of target event is located above the green arrow, it means the new approach is faster than previous approach. Details:TASing Methodology.

          +


          +

          C. On complex segments use an unbound Marker that always points at the current fastest frame number in the Piano Roll. Every time you beat the old result you're supposed to manually move the Marker higher. Thus if the new frame of target event is located above the Marker, it means the new approach is faster than the old best approach.

          +


          +

          D. On segments of any level of complexity it's recommended to use Bookmarks that are displayed in the icons column of the Piano Roll. Every time you beat the old result you're supposed to manually save the current approach to the same Bookmark slot, replacing the old best approach stored there. Thus if the new frame of target event is located above the Bookmark icon, it means the new approach is faster than the old best approach.

          +


          +


          +

          3. Comparing the state of the game at the same frame.

          +

          Choose the approach where properties of the game are more advantageous in a whole. This type of comparison is useful when you need to evaluate compound in-game situations. For example, in Formula 1 racing you have to care both about being as fast as possible and wearing tyres as little as possible, so you need to find an optimal balance on each segment of the track instead of simply rushing.

          +

          Here our segment has defined end frame, and every new test is supposed to replay the segment up to that frame. Taseditor stores this frame number in the form of the green arrow, which automatically pauses emulation when you watch new approaches. So TASer only needs to edit Input (creating new approaches), launch replaying, wait for the stopping and evaluate the result (judging by FCEUX screen or Memory Watch).

          +

          The search of approaches goes on until you're tired, or until all possible types of approaches are exhausted (then the current best approach is considered to be perfect, until new factors are found).

          +

          Programming analogy: comparing two Strings, comparing  two arrays of Integer Numbers.

          +


          +

          A. For simple segments it may be enough to just keep in mind the value of the most important property of the game state achieved in the old best approach. Every time you watch the replaying of a new approach, you can compare results of the new approach with this value. If you decide the new value is better, you have to memorize it in place of old value. Example: luck manipulation.

          +

          When there's more than one important property, it's not recommended to rely on human memory.

          +


          +

          B. On complex segments and especially on gigantic segments (e.g. with the size of a whole level of the game) use Bookmarks that store alternative branches of the movie. The best approach for playing the segment is saved into one Bookmark slot and the new approach is saved into another slot. Then you can easily switch between these slots and compare values of each property of the game state. In addition, you can point the mouse cursor to respective Bookmarks to see screenshots of the game state and visually compare their properties with current image on FCEUX screen.

          +

          To display important RAM data on screenshots you should use Lua graphical output, then Memory Watch window won't be required to judge about hidden properties, and you will be able to successfully judge by screenshots only. Details: Program Customization.

          +

          In the situation when some properties in the new approach are better and some others are worse you'll have to thoroughly weigh all of them (either in your mind or using a Lua-powered aggregate formula) and then decide which state of the game is better.

          +

          Every time you beat the old result you're supposed to manually save the new approach to the same Bookmark slot, replacing the old best approach stored there.

          +


          +
          +


          +

          After finding the fastest approach of playing the segment, a good TASer is expected to improve the entertainment value of the play through the segment. The optimality criteria in such activity may be very diverse, but the general requirement is to keep the same time of playing through the segment.

          +

          Alternatively, you can postpone the entertainment improvement of the segment and proceed to the next.

          +


          +


          +


          +


          +


          -

          Created with the Personal Edition of HelpNDoc: Single source CHM, PDF, DOC and HTML Help creation

          -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/TASEditorInside.html b/web/help/taseditor/TASEditorInside.html index 92cf2001..bd699f84 100644 --- a/web/help/taseditor/TASEditorInside.html +++ b/web/help/taseditor/TASEditorInside.html @@ -1,93 +1,288 @@ - - + + + + + - TAS Editor Inside - - - - - - - - - - + + + + + + + + TAS Editor Inside + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      TAS Editor Inside

      - -
      -
      - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      TAS Editor Inside

      + +
      +

      -

      TAS Editor Inside

      +

      TAS Editor Inside



      -

      This section of the documentation describes all ideas put into the Taseditor and reveals major details of the final implementation of TAS Editor 1.0. For more details check the source code of the program (in C++).

      -

      Taseditor is an open source program and is distributed under the MIT license which allows unrestricted use. The license was chosen to encourage modification and porting to another platforms.

      -

      You can download the source code of the FCEUX emulator with built-in Taseditor from the official SVN repository: http://sourceforge.net/p/fceultra/code/

      -

      To work with SVN you'll need some SVN client program, like TortoiseSVN.

      -

      The source code of Taseditor is well-commented, and to understand the code you only need basic skills of programming in C++ under Win32 API.

      -


      -


      -

      Ideas

      -

      The intended functionality of the program

      -


      -

      Implementation

      -

      The actual program architecture

      -


      -

      Mistake-proofing

      -

      The list of unobvious nuances

      -


      -

      FM3 format

      -

      Taseditor project file specifications

      -


      -


      -


      -


      -


      +

      This section of the documentation describes all ideas put into the Taseditor and reveals major details of the final implementation of TAS Editor 1.0. For more details check the source code of the program (in C++).

      +

      Taseditor is an open source program and is distributed under the MIT license which allows unrestricted use. The license was chosen to encourage modification and porting to another platforms.

      +

      You can download the source code of the FCEUX emulator with built-in Taseditor from the official SVN repository: http://sourceforge.net/p/fceultra/code/

      +

      To work with SVN you'll need some SVN client program, like TortoiseSVN.

      +

      The source code of Taseditor is well-commented, and to understand the code you only need basic skills of programming in C++ under Win32 API.

      +


      +


      +

      Ideas

      +

      The intended functionality of the program

      +


      +

      Implementation

      +

      The actual program architecture

      +


      +

      Mistake-proofing

      +

      The list of unobvious nuances

      +


      +

      FM3 format

      +

      Taseditor project file specifications

      +


      +


      +


      +


      +


      -

      Created with the Personal Edition of HelpNDoc: Full-featured multi-format Help generator

      -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/TASingMethodology.html b/web/help/taseditor/TASingMethodology.html index 7322ee90..2567814e 100644 --- a/web/help/taseditor/TASingMethodology.html +++ b/web/help/taseditor/TASingMethodology.html @@ -1,210 +1,411 @@ - - + + + + + - 4. TASing Methodology - - - - - - - - - - + + + + + + + + 4. TASing Methodology + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      4. TASing Methodology

      - -
      - Beginner's Guide ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      4. TASing Methodology

      + +
      +

      -

      TASing Methodology

      -


      -


      -

      This chapter is dedicated to the principal activity in TASing – the way of creating an optimal Input for any given segment of the movie. TASes look so shiny exactly because of persistent manual polishing of Input. The size of working segment can be anything, criteria and factors of optimality can vary, but the method is basically one and the same: retry all sorts of approaches and choose the best one. The only question is how to do it with minimum time and effort.

      -


      -
        -
      • Gamers erroneously think that to make a TAS you only have to complete the game once, using savestates when you make some fatal mistakes (those resulting in inability to complete current segment, for example, death of the character).
      • -
      • Newbie TASers understand that to make a beautiful TAS you have to revert and fix all noticed mistakes (e.g. even such minor flaws as stumbling over a threshold). They also complete each segment only once, but spend more time than regular players, because of saving and loading savestates much more often. For TASing simple games this can be sufficient.
      • -
      • Experienced TASers know that to make a perfect TAS it's not enough to fix all noticed mistakes. You also have to fix unnoticed mistakes. Consider unknown factors. Approach the task from an unobvious side. To do all this they play through the same segment several times, both fixing all noticed mistakes and trying to somehow avert unnoticeable mistakes.
      • +

        TASing Methodology

        +


        +


        +

        This chapter is dedicated to the principal activity in TASing – the way of creating an optimal Input for any given segment of the movie. TASes look so shiny exactly because of persistent manual polishing of Input. The size of working segment can be anything, criteria and factors of optimality can vary, but the method is basically one and the same: retry all sorts of approaches and choose the best one. The only question is how to do it with minimum time and effort.

        +


        +
          +
        • Gamers erroneously think that to make a TAS you only have to complete the game once, using savestates when you make some fatal mistakes (those resulting in inability to complete current segment, for example, death of the character).
        • +
        • Newbie TASers understand that to make a beautiful TAS you have to revert and fix all noticed mistakes (e.g. even such minor flaws as stumbling over a threshold). They also complete each segment only once, but spend more time than regular players, because of saving and loading savestates much more often. For TASing simple games this can be sufficient.
        • +
        • Experienced TASers know that to make a perfect TAS it's not enough to fix all noticed mistakes. You also have to fix unnoticed mistakes. Consider unknown factors. Approach the task from an unobvious side. To do all this they play through the same segment several times, both fixing all noticed mistakes and trying to somehow avert unnoticeable mistakes.
        -


        -

        It's rather difficult to convince yourself to spend time on alternative ways to play through the segment once it's already completed and all obvious mistakes are already fixed. After achieving the current in-game goal people usually want to set another in-game goal. But you must remember that TASer's goal is different from player's goals. So try to abstract away from the game rules and not to retreat from the segment until you complete real goal, not just player's small goal.

        -

        That's actually the most difficult part – to invent new approaches to solving one and the same task. TASers mainly consider the same approach a regular player would have used in this place of the game. That's why people mostly use evolutionary way instead of revolutionary. You keep modifying the existing basic approach, both fixing its mistakes and conducting experiments. In the process of these thoughtful modifications you enrich your knowledge base about the game, and as a result you produce an Input that isn't immediately obvious.

        -

        Of course, sometimes you have a flash of inspiration, when a revolutionary idea leads to tremendous improvements that surpass all polishing gains. People love TASing exactly for these emotional moments. Yet it doesn't exempt you from the need to polish this new revolutionary approach using the same methods to bring it even closer to an ideal.

        -

        Instead of reading the techniques described here you can just immediately start real TASing, so in a course of several projects you would work out your own methods. But most likely after a year of TASing you'll come to the described scheme of work.

        -


        -

        So, the process of creating the best Input for the segment of optimization can be basically described as a loop of fixing mistakes in previous versions of Input of the segment. A mistake is any kind of divergence from the perfect yet unknown Input. Such statement of question is very advantageous, because it means that you can gradually approach the perfect Input by making small steps that you can elaborate even without being a genius. The majority of mistakes can be successfully fixed by repeated examination and modification. That is, even when you don't have any original ideas, you can achieve a success by persistence. The successful progress motivates you to continue the work and thus prepare the ground for breakthrough ideas.

        -


        -

        To correct a mistake in the Input of a movie you have to:

        -
          -
        1. Become aware of the mistake.
        2. -
        3. Conjecture a solution.
        4. -
        5. Navigate to the place.
        6. -
        7. Apply changes.
        8. -
        9. Verify the outcome.
        10. +


          +

          It's rather difficult to convince yourself to spend time on alternative ways to play through the segment once it's already completed and all obvious mistakes are already fixed. After achieving the current in-game goal people usually want to set another in-game goal. But you must remember that TASer's goal is different from player's goals. So try to abstract away from the game rules and not to retreat from the segment until you complete real goal, not just player's small goal.

          +

          That's actually the most difficult part – to invent new approaches to solving one and the same task. TASers mainly consider the same approach a regular player would have used in this place of the game. That's why people mostly use evolutionary way instead of revolutionary. You keep modifying the existing basic approach, both fixing its mistakes and conducting experiments. In the process of these thoughtful modifications you enrich your knowledge base about the game, and as a result you produce an Input that isn't immediately obvious.

          +

          Of course, sometimes you have a flash of inspiration, when a revolutionary idea leads to tremendous improvements that surpass all polishing gains. People love TASing exactly for these emotional moments. Yet it doesn't exempt you from the need to polish this new revolutionary approach using the same methods to bring it even closer to an ideal.

          +

          Instead of reading the techniques described here you can just immediately start real TASing, so in a course of several projects you would work out your own methods. But most likely after a year of TASing you'll come to the described scheme of work.

          +


          +

          So, the process of creating the best Input for the segment of optimization can be basically described as a loop of fixing mistakes in previous versions of Input of the segment. A mistake is any kind of divergence from the perfect yet unknown Input. Such statement of question is very advantageous, because it means that you can gradually approach the perfect Input by making small steps that you can elaborate even without being a genius. The majority of mistakes can be successfully fixed by repeated examination and modification. That is, even when you don't have any original ideas, you can achieve a success by persistence. The successful progress motivates you to continue the work and thus prepare the ground for breakthrough ideas.

          +


          +

          To correct a mistake in the Input of a movie you have to:

          +
            +
          1. Become aware of the mistake.
          2. +
          3. Conjecture a solution.
          4. +
          5. Navigate to the place.
          6. +
          7. Apply changes.
          8. +
          9. Verify the outcome.
          -


          -

          1. Realizing a mistake happens either when watching the movie in Read-Only mode or right when recording/editing the Input.

          -
          - - - +


          +

          1. Realizing a mistake happens either when watching the movie in Read-Only mode or right when recording/editing the Input.

          +
          +

          Comment: Instead of detecting a tangible mistake TASers often just assume that current segment is still improvable. It's always wise to doubt the perfectness of current result and try experimenting with the Input – sometimes you indeed find unused possibilities.

          -
          + + +
          +

          Comment: Instead of detecting a tangible mistake TASers often just assume that current segment is still improvable. It's always wise to doubt the perfectness of current result and try experimenting with the Input – sometimes you indeed find unused possibilities.

          +
          -

          -

          -

          2. The means of solving the mistake are either immediately obvious or are found experimentally. In rare cases you have to resort to calculations and comparisons. A correctly chosen segment usually encompasses all key factors of optimality. The information from previous or next segments is rarely needed.

          -
          - - - +


          +

          2. The means of solving the mistake are either immediately obvious or are found experimentally. In rare cases you have to resort to calculations and comparisons. A correctly chosen segment usually encompasses all key factors of optimality. The information from previous or next segments is rarely needed.

          +
          +

          Comment: Sometimes while fixing one mistake we unwittingly create another mistake. In this case the optimization process would go in wrong direction, but fortunately such situations are extremely rare in TASing, because videogames are much more straightforward than real life, so player can find all factors and an unambiguous criterion of optimality. Taseditor additionally simplifies the process by data visualization.

          -
          + + +
          +

          Comment: Sometimes while fixing one mistake we unwittingly create another mistake. In this case the optimization process would go in wrong direction, but fortunately such situations are extremely rare in TASing, because videogames are much more straightforward than real life, so player can find all factors and an unambiguous criterion of optimality. Taseditor additionally simplifies the process by data visualization.

          +
          -


          -

          3. The ability to navigate to the place of making the mistake is the essential distinction between TASing and normal speedrunning. Regular players can detect the mistake post factum, but it's TASers who always return back to correct it.

          -

          In traditional method of TASing the navigation may take noticeable amount of time and effort. Taseditor makes the navigation much faster.

          -
          - - - +


          +

          3. The ability to navigate to the place of making the mistake is the essential distinction between TASing and normal speedrunning. Regular players can detect the mistake post factum, but it's TASers who always return back to correct it.

          +

          In traditional method of TASing the navigation may take noticeable amount of time and effort. Taseditor makes the navigation much faster.

          +
          +

          Comment: Sometimes the place of making the mistake is located long before the segment where it is revealed. In this case you have to find the segment affecting the mistake and edit it according to the information given by the played segment. And in this case the speed of navigation between those two segments is even more important.

          -
          + + +
          +

          Comment: Sometimes the place of making the mistake is located long before the segment where it is revealed. In this case you have to find the segment affecting the mistake and edit it according to the information given by the played segment. And in this case the speed of navigation between those two segments is even more important.

          +
          -


          -

          4. Applying modifications to Input is how you make your thoughts real. The less the delay between an idea and its implementation is, the better.

          -

          In the traditional method of TASing the Input modification generally takes longer, because in addition to rewriting erroneous frames you also have to rewrite adjacent frames  In Taseditor this is often not necessary.

          -
          - - - +


          +

          4. Applying modifications to Input is how you make your thoughts real. The less the delay between an idea and its implementation is, the better.

          +

          In the traditional method of TASing the Input modification generally takes longer, because in addition to rewriting erroneous frames you also have to rewrite adjacent frames  In Taseditor this is often not necessary.

          +
          +

          Comment: Since any Input modification entails a change in the game flow, sometimes even in Taseditor you have to resync the old Input that follows the place of fixing mistake.

          -
          + + +
          +

          Comment: Since any Input modification entails a change in the game flow, sometimes even in Taseditor you have to resync the old Input that follows the place of fixing mistake.

          +
          -


          -

          5. To see the outcome you need to resume playing the movie from the beginning of current segment of right from the frame of fixing the mistake. There's no need to re-check previous segments of the movie, because the mistake fixing affects only subsequent events.

          -
          - - - +


          +

          5. To see the outcome you need to resume playing the movie from the beginning of current segment of right from the frame of fixing the mistake. There's no need to re-check previous segments of the movie, because the mistake fixing affects only subsequent events.

          +
          +

          Comment: Although, when you're making an entertaining playthrough instead of a pure speedrun, after fixing a mistake (e.g. making the movement trajectory more smooth) you should ensure that this correction fits with the general sequence of in-game events, so it's recommended to rewatch some previous events together with the current segment.

          -
          + + +
          +

          Comment: Although, when you're making an entertaining playthrough instead of a pure speedrun, after fixing a mistake (e.g. making the movement trajectory more smooth) you should ensure that this correction fits with the general sequence of in-game events, so it's recommended to rewatch some previous events together with the current segment.

          +
          -

          You almost always have to watch the current segment up to its end, that is, to the moment when the target event occurs, so that you can confidently apply the optimality criterion. Because the correction may seem profitable at first but appear worse in the end.

          -

          After evaluating the outcome, the mistake is either considered to be fixed/non-existent, or you have to return to step 2 and rethink the situation.

          -


          -
          -

          -

          -

          Before Taseditor, all mistakes (both explicit and supposed) were being fixed by creating and reloading savestates. If you're not familiar with the traditional method of TASing, here's its basic principles:

          -
            -
          • The game emulation is almost always paused. You only unpause it to rewatch finished segments.
          • -
          • TASer sequentially types the Input into frames pointed by the Playback cursor. You see the outcome of the committed Input next frame (or sometimes in several frames). Experienced TASers create a new savestate after each hard-to-reproduce action, so they are able to return back without the need to replay the whole segment from the beginning.
          • -
          • To correct a mistake, TASer returns to the supposed place of making the mistake and rerecords the whole Input, starting from the frame that needs to be changed. If there was a savestate created at this frame, you can instantly load the savestate in Read+Write mode and begin typing buttonpresses right away. But if you only have a savestate created at some distance before the frame, there are two options. Option 1: load the nearest savestate in Read-Only mode and replay the movie up to the needed frame, then switch back to Read+Write mode and start the correction, thus not touching the Input in the interval from the savestate frame to the mistake frame. Option 2: just load the nearest savestate in Read+Write mode and repeat the old Input by memory, thus rewriting it up to the needed frame, and then start the correction. The 2nd way is used more often, because after the nearest savestate there's usually an easy-to-reproduce Input (e.g. simply holding R + B). Also, upon arriving to the supposed frame of the mistake, an experienced TASer mechanically creates a savestate (just in case!), so next time he will be able to return directly to the frame, without wasting time on navigation. Such a prudence makes sense, because mistakes are seldom fixed at the first attempt, usually you need to repeatedly rerecord the same section of Input, starting from about the same frame.
          • -
          • The disadvantages of the traditional method clearly reveal when you need to see a distant result of your Input (for example, you press the button now, but the roulette only stops in several seconds). In such cases TASer makes a savestate before entering the Input, records the decisive Input and makes a savestate after it, then unpauses the emulator and carelessly (suboptimally) plays through the game up to the point of seeing the result. If the result is satisfactory, TASer loads the savestate made after the decisive Input and records an optimal playthrough, already being sure in successful outcome. And if the result is unsatisfactory, TASer loads the initial savestate, changes the decisive Input and repeats previous actions (creates a savestate after the Input and hastily plays up to the result). And this process may go for a long while.
          • -
          • In order to copy an old Input (for example, the complex acceleration of Mario at the beginning of every level), TASer either learns the button combination by heart or copies it in parts by making several jumps between the source and the destination. First the game is sent to the place of old Input (by loading the savestate prepared at that frame) to watch the replay in Read-Only mode and memorize a few buttonpresses, then it's sent to the current segment (by loading the latest savestate in Read+Write mode) to lay out the buttonpresses. This way sounds tiresome, but if you keep moving both savestates a bit forward after every jump, the navigation between source and destination becomes rather quick. Still, when TASers need to copy a long sequence of buttonpresses, they use an external editor of Input, allowing to copy/paste. But the downside is that switching contexts is very distracting, so often it's less troublesome to just copy the Input manually.
          • -
          • To examine the current progress, TASer makes a savestate, turns off the Recording and loads the savestate left at the beginning of current level (usually it's the slot assigned to a rarely used key, such as F10). Then he unpaused the emulator and watches the movie like an outsider. To continue the recording, he switches to Read+Write mode and returns directly to the latest recorded frame by loading the latest savestate (usually it's the most often used slot, like F1). If while watching TASer decides to modify the old Input, he makes a savestate at this point, switches to Read+Write and loads the just created savestate. Beforehand, you should make sure the last state of the movie is saved to both F1 and another slot that won't be used in your experiments with the old Input. This is necessary in case your experiments fail, so you could restore the old movie even if the F1 slot becomes overwritten in the course of the experiments.
          • -
          • So, the majority of the 10 available slots is used for navigation between different moments of the game. Or, using Taseditor's terms, they are used for Playback cursor navigation along the movie. The 10 slots are more than enough to teleport back and forth among all places of interest, even when current segment is very large. Usually 3-5 slots are enough. Experienced TASers juggle these slots with astounding speed.
          • -
          • A couple of another slots are used to store alternative strategies of playing. When you don't know which approach to playing a large segment (e.g. a whole level of the game) will be better, you first polish the 1st approach and save it into a separate slot (say, F8), then you polish the 2nd approach and save it into an adjacent slot (e.g. F7). After that you can alternately load these slots (or even alternately watch the two branches of the movie) and choose the best one, save it to F1 and continue TASing in this branch.
          • +

            You almost always have to watch the current segment up to its end, that is, to the moment when the target event occurs, so that you can confidently apply the optimality criterion. Because the correction may seem profitable at first but appear worse in the end.

            +

            After evaluating the outcome, the mistake is either considered to be fixed/non-existent, or you have to return to step 2 and rethink the situation.

            +


            +
            +


            +

            Before Taseditor, all mistakes (both explicit and supposed) were being fixed by creating and reloading savestates. If you're not familiar with the traditional method of TASing, here's its basic principles:

            +
              +
            • The game emulation is almost always paused. You only unpause it to rewatch finished segments.
            • +
            • TASer sequentially types the Input into frames pointed by the Playback cursor. You see the outcome of the committed Input next frame (or sometimes in several frames). Experienced TASers create a new savestate after each hard-to-reproduce action, so they are able to return back without the need to replay the whole segment from the beginning.
            • +
            • To correct a mistake, TASer returns to the supposed place of making the mistake and rerecords the whole Input, starting from the frame that needs to be changed. If there was a savestate created at this frame, you can instantly load the savestate in Read+Write mode and begin typing buttonpresses right away. But if you only have a savestate created at some distance before the frame, there are two options. Option 1: load the nearest savestate in Read-Only mode and replay the movie up to the needed frame, then switch back to Read+Write mode and start the correction, thus not touching the Input in the interval from the savestate frame to the mistake frame. Option 2: just load the nearest savestate in Read+Write mode and repeat the old Input by memory, thus rewriting it up to the needed frame, and then start the correction. The 2nd way is used more often, because after the nearest savestate there's usually an easy-to-reproduce Input (e.g. simply holding R + B). Also, upon arriving to the supposed frame of the mistake, an experienced TASer mechanically creates a savestate (just in case!), so next time he will be able to return directly to the frame, without wasting time on navigation. Such a prudence makes sense, because mistakes are seldom fixed at the first attempt, usually you need to repeatedly rerecord the same section of Input, starting from about the same frame.
            • +
            • The disadvantages of the traditional method clearly reveal when you need to see a distant result of your Input (for example, you press the button now, but the roulette only stops in several seconds). In such cases TASer makes a savestate before entering the Input, records the decisive Input and makes a savestate after it, then unpauses the emulator and carelessly (suboptimally) plays through the game up to the point of seeing the result. If the result is satisfactory, TASer loads the savestate made after the decisive Input and records an optimal playthrough, already being sure in successful outcome. And if the result is unsatisfactory, TASer loads the initial savestate, changes the decisive Input and repeats previous actions (creates a savestate after the Input and hastily plays up to the result). And this process may go for a long while.
            • +
            • In order to copy an old Input (for example, the complex acceleration of Mario at the beginning of every level), TASer either learns the button combination by heart or copies it in parts by making several jumps between the source and the destination. First the game is sent to the place of old Input (by loading the savestate prepared at that frame) to watch the replay in Read-Only mode and memorize a few buttonpresses, then it's sent to the current segment (by loading the latest savestate in Read+Write mode) to lay out the buttonpresses. This way sounds tiresome, but if you keep moving both savestates a bit forward after every jump, the navigation between source and destination becomes rather quick. Still, when TASers need to copy a long sequence of buttonpresses, they use an external editor of Input, allowing to copy/paste. But the downside is that switching contexts is very distracting, so often it's less troublesome to just copy the Input manually.
            • +
            • To examine the current progress, TASer makes a savestate, turns off the Recording and loads the savestate left at the beginning of current level (usually it's the slot assigned to a rarely used key, such as F10). Then he unpaused the emulator and watches the movie like an outsider. To continue the recording, he switches to Read+Write mode and returns directly to the latest recorded frame by loading the latest savestate (usually it's the most often used slot, like F1). If while watching TASer decides to modify the old Input, he makes a savestate at this point, switches to Read+Write and loads the just created savestate. Beforehand, you should make sure the last state of the movie is saved to both F1 and another slot that won't be used in your experiments with the old Input. This is necessary in case your experiments fail, so you could restore the old movie even if the F1 slot becomes overwritten in the course of the experiments.
            • +
            • So, the majority of the 10 available slots is used for navigation between different moments of the game. Or, using Taseditor's terms, they are used for Playback cursor navigation along the movie. The 10 slots are more than enough to teleport back and forth among all places of interest, even when current segment is very large. Usually 3-5 slots are enough. Experienced TASers juggle these slots with astounding speed.
            • +
            • A couple of another slots are used to store alternative strategies of playing. When you don't know which approach to playing a large segment (e.g. a whole level of the game) will be better, you first polish the 1st approach and save it into a separate slot (say, F8), then you polish the 2nd approach and save it into an adjacent slot (e.g. F7). After that you can alternately load these slots (or even alternately watch the two branches of the movie) and choose the best one, save it to F1 and continue TASing in this branch.
            -


            -

            As you see, almost everything in the traditional method of TASing is done using savestates (Bookmarks). In Taseditor some of their functions are replaced by the Greenzone and the History Log, yet Bookmarks still play important role, allowing to keep alternative branches of the movie in a single project. The Playback cursor navigation now can be done faster by either drag'n'drop or mouse wheel. In fact, now you don't need to put Playback cursor to the frame of modification, you can just scroll the Piano Roll to the place and change the Input by mouse.

            -

            Since the Recording is less effective than direct editing, there's no more need to constantly switch modes. Now the emulator is always in Read-Only mode.

            -

            The game is always paused, as before. But now you are seeing the outcome of your Input only when you actually want to see it. At first this may seem inconvenient (as you don't feel the habitual feedback from your keypresses), but it's actually very advantageous, because it means the higher level of independence from the game. Instead of the standard mechanism of "involvement into the gameplay" there are other mechanisms of data transmission. So in any case you will receive all needed information on how the game interprets your Input, it's just that this data stream won't continually flow into your mind, it will be delivered on command.

            -

            And when it's really necessary, you can have an intensified feedback by switching to the third method of TASing in Taseditor.

            -

            Let's review pros and cons of all three methods, one by one.

            -


            -
            - - - +


            +

            As you see, almost everything in the traditional method of TASing is done using savestates (Bookmarks). In Taseditor some of their functions are replaced by the Greenzone and the History Log, yet Bookmarks still play important role, allowing to keep alternative branches of the movie in a single project. The Playback cursor navigation now can be done faster by either drag'n'drop or mouse wheel. In fact, now you don't need to put Playback cursor to the frame of modification, you can just scroll the Piano Roll to the place and change the Input by mouse.

            +

            Since the Recording is less effective than direct editing, there's no more need to constantly switch modes. Now the emulator is always in Read-Only mode.

            +

            The game is always paused, as before. But now you are seeing the outcome of your Input only when you actually want to see it. At first this may seem inconvenient (as you don't feel the habitual feedback from your keypresses), but it's actually very advantageous, because it means the higher level of independence from the game. Instead of the standard mechanism of "involvement into the gameplay" there are other mechanisms of data transmission. So in any case you will receive all needed information on how the game interprets your Input, it's just that this data stream won't continually flow into your mind, it will be delivered on command.

            +

            And when it's really necessary, you can have an intensified feedback by switching to the third method of TASing in Taseditor.

            +

            Let's review pros and cons of all three methods, one by one.

            +


            +
            +


            -

            The three methods of TASing in Taseditor:

            -


            - -
              -
            • navigating the Input using the Playback cursor by jumping to Bookmarks
            • -
            • recording sequences of Input using the keyboard/joypad
            • -
            • watching interim results of the Input automatically
            • -
            -


            - -
              -
            • navigating the Input using the mouse
            • -
            • editing the Input using the mouse/keyboard/joypad
            • -
            • watching interim or final results of the Input by user command
            • -
            -


            - -
              -
            • navigating the Input using the mouse
            • -
            • editing the Input using the mouse/keyboard/joypad
            • -
            • watching interim or final results of the Input automatically
            • -
            -


            -
            + + +
            +


            +

            The three methods of TASing in Taseditor:

            +


            + +
              +
            • navigating the Input using the Playback cursor by jumping to Bookmarks
            • +
            • recording sequences of Input using the keyboard/joypad
            • +
            • watching interim results of the Input automatically
            • +
            +


            + +
              +
            • navigating the Input using the mouse
            • +
            • editing the Input using the mouse/keyboard/joypad
            • +
            • watching interim or final results of the Input by user command
            • +
            +


            + +
              +
            • navigating the Input using the mouse
            • +
            • editing the Input using the mouse/keyboard/joypad
            • +
            • watching interim or final results of the Input automatically
            • +
            +


            +
            -


            -


            -


            -


            -


            +


            +


            +


            +


            +


            -

            Created with the Personal Edition of HelpNDoc: Easily create Web Help sites

            -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/TASingProcess.html b/web/help/taseditor/TASingProcess.html index 131fac4d..001e20cf 100644 --- a/web/help/taseditor/TASingProcess.html +++ b/web/help/taseditor/TASingProcess.html @@ -1,179 +1,374 @@ - - + + + + + - 3. TASing Process - - - - - - - - - - + + + + + + + + 3. TASing Process + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      3. TASing Process

      - -
      - Beginner's Guide ››
      -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - -

      -

      TASing Process

      -


      -


      -

      TASing is about striving for an absolute perfectness. For TASers, a game is more than just an amusement, it's an interesting and complex task.

      -

      People enjoy solving creative tasks, because it allows them to express their individuality and improve various skills. However, complicated tasks require both inventiveness and methodicalness. This Manual describes dry and methodical side of TASing, as for inventiveness – you'll have to show it yourself in real setting.

      -

      In general, to create a perfect (or very close to perfect) playthrough of the game you have to record an imperfect walkthrough and then work on consecutive improvements of its separate parts. When every fragment of the movie is perfect, we may consider the whole TAS to be perfect as well.

      -

      The concentration of efforts on small segments of the movie is the key to success. Every working segment has to be large enough to represent an adequate subtask, but small enough to make the task simple.

      -

      Without such structuring an effective and comfortable TASing would not be possible. There's too many factors affecting the final result of the game, and some of those factors append or contradict each other. Human memory is not enough to keep and calculate all interconnections of the game factors within a large segment of the playthrough. Therefore, when TASers deal with long play sessions, they aren't different from regular players who are carried by the temptation to use the first observations as a base for making decisions. But regular players can get away with such carefree approach, while TASers would end up with a clearly imperfect walkthrough.

      -

      Thus real TASing implies that segments are small. Much smaller than a single level of a typical videogame. The whole process of TASing may be portrayed like this: a man watches the recording of his own unfinished playthrough of the game, selects a small piece of the movie and throws all forces into improving it, then selects another piece and so on until the end of the game.

      -

      Of course, it's an incomplete picture, because besides the movie editing TASers also research and experiment with the game (to expose hidden factors) and do many other things. But that's beyond the scope of this Guide.

      -

      The skill of choosing adequate segments comes with experience. Many TASers don't even think what makes them spontaneously focus on a segment of the game and unconsciously limit the beginning and the end of current work. Some believe that they simply record the movie frame-by-frame in succession, but if you watch it from outside you can note that those repeated rerecords occur within a window of 20-200 frames, and the window goes forward the movie by making jumps (the end of previous segment becomes the beginning of next segment). Consider watching live stream videos of TASing, and you'll see certain regularities in handling savestates.

      -

      Here we'll try to analyze the behavior, in order to learn how to define current segment limits sensibly. And then practical TASing will make you do it mechanically.

      -


      -

      An adequate segment (subtask) is supposed to give TASer a consistent goal and simple means to reach it.

      -

      The goal of a segment playthrough is usually to achieve certain in-game event. For example, the goal of playing through the whole game is the event when "THE END" text appears on the screen. The goal of one level can be such event as "the value of the level counter in RAM was increased" or simply "the screen faded at the end of current level". And the goal of a small segment may be something like "the character successfully landed on the other side of the pit". These intermediate goals are defined by the context.

      -

      Based on the goal, TASer defines the optimality criterion in mind. The criterion is the rule which lets you compare any two versions of playing through the current segment of the game. When you're TASing, it's not enough to simply reach the goal, you have to try many approaches to reaching it, and then choose the best approach of all. For example, in a speedrun the best approach to playing a segment is usually the one in which the target event occurs as early as possible. E.g. if the 1st approach to playing the segment made the event occur at frame 350, and the 2nd approach made it appear at frame 340, then the 2nd approach is better than the 1st, and the final movie should contain exactly the 2nd approach.

      -

      There's a lot of means for reaching the target event. In theory, any gameplay aspect (including those not planned by developers) may help or impede the progress in some way. So, to cope with this vague multitude of possibilities you should regard all aspects of the game as optimality factors.

      -

      -

      An optimality factor is an aspect of the game that directly affects optimality of playing current segment. The word "directly" implies a monotonous dependence of outcome from applying the factor. For example, on this picture there's no monotonous dependence between the distance to finish and the duration of holding Right. Pressing the same R button either makes Mario be closer to the finish, or moves him away, depending on his position.

      -

      When people perceive such segment in a whole, it's difficult to guess the best moment to release the R button, when to press the L button and so on. So, in order to simplify the understanding of complex dependencies (and thus reveal factors), such segments should be broken into several subsegments.

      -

      Correct statement of question usually cuts off many irrelevant possibilities. For example, regular player could wait until the difficult enemy character walks away, but in a speedrun such tactic is not considered.

      -

      Thus even in an open-world game TASer is left with a limited set of useful actions and in-game indicators that must be followed while polishing one segment. And the less the segment is, the more limited is this set, so it's easier to find an ideal sequence of actions by going over combinations of factors.

      -

      On the other hand, the less the segment is, the less its goal intersects with the final goal of the TAS. The final goal is to make perfect walkthrough, e.g. the fastest in the world (which means the frame counter at the end of the movie should be as low as possible). But in terms of every specific segment the goal may be completely different, sometimes even opposite (for example, to stay in bonus stage as long as possible, which then grants time saving at another point of the game). That's why in very small segments the optimality criterion is not used, and playing such micro-segment is only evaluated as a part of a full-fledged segment.

      -

      For example, when your character is jumping over a pit and shooting enemies at the same time, every bullet release can be considered a separate subsegment (so it becomes easy to isolate such factors as "recharge timer", "max 3 bullets on screen" and so on). But then, when comparing approaches, you should compare different versions of jumping over the pit. Even if the 1st approach to jumping (which ends at the frame 350) allowed you to shoot two enemies and the 2nd approach (which ends at frame 340) allowed to shoot only single enemy, you are supposed to choose the 2nd approach, because the optimality criterion of the unbroken segment fits the final goal of the speedrun better.

      -

      While TASing you have to maintain an optimal balance between the necessity to decrease segments in order to grasp factors and the need to increase them in order to use a relevant criterion. This skill comes with time, so don't sweat it and just rely on your intuition.

      -


      -
      - - - -

      Let's have an example when the segment is too large. In a Super Mario Bros speedrun you are expected to reach the end of World 1-1 as fast as possible, which means you have to maximize the X coordinate of the character moving from left to right. The basic premise is that at the beginning of the level the X value equals zero and at the end of the level it is one thousand. Using gamepad buttons you can influence the coordinate in various ways.

      -

      If we take the whole level from the moment X = 0 to the event X = 1000 as our working segment, we can immediately see the optimality criterion (the best approach will be the one with minimal value of the frame counter when X >= 1000), but we can't see definite factors. How exactly we're supposed to press buttons to get the X = 1000 within minimal number of frames? Well, we can apply a regular player's logic and intuition. When we press the R button, the X coordinate usually increases, and with the L button it decreases. So the most obvious decision is to hold the R button and see how many frames is needed to grow the value of X to one thousand. When testing such approach in emulator, it appears that Mario is hampered by obstacles and the X coordinate does not grow, even though the R button is held. This way a new factor comes to light – the need to jump over obstacles and pits. Using the A button Mario eventually reaches the X = 1000 event, and the optimality criterion can eliminate all alternative playthroughs where the A button presses were ill-timed (e.g. where Mario stumbled over edges of pipes, the frame counter at the end of the segment was higher).

      -

      Now the player (or rather, TASer who is stuck in player's mindset) may think that all factors are applied and the segment is perfect. But it isn't. Super Mario Bros has somewhat complex physics engine. The X coordinate is influenced by current horizontal speed, and speed is influenced by acceleration. Acceleration is affected by the B button, skidding, Mario's direction and air-ground state. There are also teleporter pipes and useful glitches like the "flagpole glitch" and so on. A lot of things to bear in mind. But, according to certain research, human working memory can only store about 7 objects, thus some factors inevitably slip away when you're editing Input on large segment. You'd better shrink the segment to such a scale which reveals factors individually or in a small group.

      -

      If we focus on the segment from X = 0 to X = 100, the optimality criterion will be the same, but now it also becomes obvious that in the first half of the segment Mario runs slower, and in the second half he runs with constant speed which can be considered maximum. This way you begin to appreciate the acceleration factor, so you add the RAM address to Memory Watch and start analyzing possible ways to influence the acceleration. After some experiments with turning and jumping you can discover more factors. As a result, you're going to find an intricate combination of R, L, B and A buttonpresses that makes the event X = 100 occur faster than simply holding R and B. And even if the new playthrough of the segment is only several frames faster than old, it's much closer to perfectness.

      -
      -
      -


      -
      - - - -

      Now let's take a look at another extreme. When segment is too small, its optimality criterion may contradict the final goal of the TAS.

      -

      First, if you get carried away by maximizing speed and acceleration in equal intervals between every next hundred of pixels, you may forget about the shortcut pipe, because diving into pipes resets speed value to zero, which contradicts with the goal of current segment. In short term the diving factor is disadvantageous for a speedrunner, and its long-term profit may be overlooked when you're busy with habitual actions.

      -

      -

      In this case the segment was chosen without much foresight, and as a consequence it sprouted wrong criterion of optimality ("the frame counter at the event X = 200 must be minimal"). Instead, the segment should end at the moment when any Down button press starts diving animation.

      -

      Of course such mistakes are often noticed when replaying finished movie on a fresh mind, but sometimes the situation is less obvious and is only revealed after publishing.

      -


      -

      Second, in the same SMB game after diving into the pipe (World 1-1) you have to reach the exit to the right. It may seem necessary to start maximizing speed from the very beginning. But as you may see in the picture, within first dozen of frames it's better to hold the L button instead of R, so that Mario lands slightly aloof from the wall that needs to be jumped over. If you hold R too early, Mario will land close to the wall and will have to jump vertically, thus losing gathered speed.

      -

      This peculiarity is not so obvious when you choose optimizing the segment from the event Mario appears to the Mario lands event. The optimality criterion of such small segment will direct you to wrong sequence of buttonpresses.

      -

      Here you should choose the segment from the frame when Mario appears to the moment of overcoming the corner of the wall.

      -

      Unfortunately, even experienced TASers not always choose correct limits right away. Sometimes you have to rethink and redo, throw away results of many tests and change the scale of the segment, play the same part of the game many times again.

      -
      -
      -


      -

      As you might have noticed, this document avoids measuring segments in real frames of the movie. Because actual size of segment varies from game to game and from stage to stage. Some parts of the game contain so little possibilities that they can last for more than a thousand of frames and still be easy to play and replay. By the way, some segments don't even need to be played more than once, since they are so simple that any successful playthrough is optimal (for instance, watching unskippable cutscenes between levels). And on the contrary, some stages of the game are supersaturated with events and factors, so you are going to sweat even over a dozen of frames.

      -

      Experienced TASers regard every segment individually (although they don't think too much about it). It's bad idea to choose the next segment by the same principle as previous, this would only work well in extremely repetitive games.

      -

      If you want, you can limit the end of current segment by a fixed frame number (e.g. set the goal to maximize the X coordinate value when the frame counter = 200). But usually it's more convenient to associate the end with some small frontier of the game (like passing over a trap or defeating another enemy) – then the goal itself is going to suggest you basic means for reaching it. The task "touch a flower as fast as possible" sounds more natural (for a gamer) than the task "at the frame 300 become as close to the flower as possible".

      -

      In the vast majority of video games the gameplay divides into "rooms", "enemy waves" and "traps", which are always separated by short periods of relaxation. Even in constantly scrolling and open-world games the level design ensures that there are intense moments and filler intervals between them. The truth is, game designers also structure player's task into subtasks, and in some cases TASer can even borrow the prepared segmentation. Just don't forget to critically assess it and subdivide into more subsegments when needed. Though, such subdivision will naturally take place in the process of editing Input on a excessively large segment. So TASing doesn't always require intense intellectual efforts. If you're skillful and smart, most of time you can just go with the flow and enjoy TASing no less than conventional gaming.

      -

      All this can be compared to how writers divide their books into chapters (game levels), and chapters into paragraphs and sentences (segments) in order to aid with comfortable reading and comprehending author's ideas. A regular reader (player) is satisfied with the author's subdivision, but a literary critic (TASer) needs to be able to "read between lines" by dividing text his own way.

      -

      For example, in Super Mario Bros every group of enemies is separated by a quiet space which doesn't require any skills, and it can be light-heartedly ran over or jumped over while holding Right (granted that Mario speed is already at maximum). So you don't even need TAS tools to be perfect at these moments. These intervals are the most suitable place to set a goal – if you mark an end of the segment at such place, the optimality criterion won't contradict with final goal of TAS for sure. And usually these moments occur often enough so the segment between them is of an acceptable size.

      -


      -
      -


      -

      The division to segments was always present in TASing, but Taseditor allows to accentuate the process visually. Here you can mark the beginning and the end of a segment using Markers or Bookmarks. Thanks to the visible boundaries you won't be distracted onto adjacent Input and can focus on analyzing only closest factors.

      -

      The frame of current segment beginning is usually chosen when watching a test playthrough of the current segment. When recording or watching such playthrough you already pick one or two key factors of optimality. So it's only logical to start the segment at the moment when these factors join into force or dramatically change the behavior. For example, at the beginning of every level you usually start a new segment, because that's the point where you regain the ability to move forward (after the cutscene between levels ends). So it's wise to set a Marker or a Bookmark at the beginning of every level, thus marking both the level boundary and the beginning of current work segment.

      -

      And if in the process of optimizing the segment you reveal some factors that join into force earlier than current beginning of the segment, you can always adjust the chosen boundaries of the segment, or break it in two subsegments.

      -

      -The ending frame of current segment is more mobile than the frame of beginning. When you define your goal (e.g. to make the X coordinate reach the value of 50) you can mark the end of current segment by setting a Marker/Bookmark to the frame where current imperfect playthrough accomplishes this goal. Then by polishing the Input you try to reach the goal (X = 50) at an earlier frame. And if in the process of modifying and testing a new Input you discover that the goal indeed can be reached earlier, you move the closing Marker/Bookmark up (to the frame of the improved end). After that you continue testing new approaches, searching for even better one until you don't feel any more potential. In traditional TASing this is exactly how the main Bookmark (storing current best playthrough of the segment) gradually moves up.

      -

      Well, sometimes you can indulge in laziness and avoid marking the end of current segment, instead you just keep the goal in mind and remember the number of the frame where the target event occurs in the best case so far. Such behavior is reasonable when the segment is very simple and you don't plan to redo it many times.

      -

      Moreover, in many platformer games where the player character has constant running speed most of segments can be played optimally from the first try (you just have to hold the Right button and maybe jump over trivial obstacles). So if you don't see any obvious mistakes and don't intend to search for hidden flaws, you may as well skip the segment shaping, just proceed to next segment right away. Such simple games are especially suitable for newbie TASers, because TASing them is very similar to casual playing through videogames using savestates (when you only revise the most obvious mistakes, like falling into a pit, and ignore non-fatal roughness).

      -

      But in complex TASes, where the mind is occupied with many optimality factors, you shouldn't hurry. To make your thought process more precise, you'd better be perfectly aware of current segment boundaries. So mark the beginning of any difficult segment with a Marker, and mark the end by setting a Bookmark every time you find an improvement (use one and the same slot). Since it's not easy to find an improvement when dealing with difficult tasks, don't expect you'll have to re-set the Bookmark too often.

      -

      When you're confident you've found perfect solution of the segment, move to the next segment. Don't remove old Markers, since they may be useful in future, in case you begin doubting the perfectness of your decisions (e.g. after finding a new trick). The logic of movie dividing will most likely remain the same even after finding the new factor (the trick).

      -

      Also, if in the middle of optimization process you become confident you've found perfect Input for the first half (or a third) of current segment, you can divide the segment in two and focus on optimizing the remaining section. Such situations often rise when the initially chosen segment was too large and its logical parts naturally emerged in the process of editing the Input.

      -


      -

      So, if you don't like to keep things organized, you can avoid Markers and Bookmarks whatsoever, working mostly in terms of fuzzy in-game concepts and imagining segments as some emotional sequences of events. Unfortunately, the data about fuzzy goals also occupies part of human working memory, and as a result you won't have enough resources to keep all optimality factors in mind. And you won't even notice how you've overlooked a multitude of possibilities.

      -

      On the contrary, if you like to keep an order, it's recommended to accompany Markers with text Notes, either before, or during, or after the optimization of the current segment. For example, make up a name for the segment or put a tag. This way you document the development of the TAS during actual TASing, give an objective meaning to the Input appearing in the process. This is especially useful when TASing in co-authorship. But even when working alone, you may notice the documentation from previous levels motivates you to carry on. It only takes seconds to type that kind of texts, and then it helps not to abandon the project.

      -

      Notes also help to better unlock the potential of tricks and bugs of the game. By writing the text you actually formalize your knowledge about the described phenomenon. When the essence of the trick is kept in your mind, you may think that you already know everything about it, and that your current TAS uses the trick the best way possible. But when you construct an objective model (a verbal description of the trick) you often find its new sides.

      -

      It's not uncommon for TASVideos.org to see how one TASer read the description of a trick in the submission text written by another TASer and found a way to use the trick better than original author. There were also cases when author himself reads his recent submission, facepalms and urgently records an improvement.

      -


      -
      -


      -

      Making a perfect TAS can take anything from several days to several years, depending on complexity of the chosen game. Most of that time is spent on finding an ideal sequence of buttonpresses for every segment.

      -

      Often it seems right away that current Input is already the best possible. But usually it's not so, especially if you make the conclusion judging by the external image of the emulated game instead of its internal state (Memory Watch). So it's always reasonable to suppose that current result is not perfect. If you don't see any mistakes or potential improvements at the moment, try to watch the segment together with several previous segments (e.g. watch the last half a minute of your movie), because it's possible that previous segments contain some unregistered optimality factors that have an effect on current segment. And if you still don't get any ideas, consider moving to next segment, but don't completely refuse further attempts to criticize and improve finished segments.

      -

      Rewatch the finished part of your movie from time to time – either from the very beginning, or from the beginning of current level – and try to notice imperfections. Taseditor allows to edit Input in any part of the movie while the movie is still playing, so you can quickly test any spontaneous idea right when it comes to your mind. If the new idea appears to be unsuccessful, just undo latest changes or load the Bookmark containing the last stable state of the movie.

      -

      -And if the new idea in fact improves you TAS, after a joyful anticipation you have to ensure that all the following segments of Input sync to the game (because implementing the idea has changed the flow of the game). Most of time it's not necessary to redo all the following Input. Usually you only have to delete or insert a few frames (thus shifting all following segments up or down), or modify several segments between the place of implementing the new idea and the nearest checkpoint (the end of current level, etc). Checkpoints usually reset many in-game properties to default value (e.g. they require you to walk over specific platform, thus equalizing the Y coordinate), so after the checkpoint you old Input will sync with new timeline of the game once you adjust it to match the flow of game events.

      -

      Anyway, even in cases when you have to redo considerable parts of the movie, resyincing is much easier than TASing from zero ground, because now you know the best approach for each segment and only have to match your previous results. And sometimes you can even excel them, because, when you're doing these forced modifications in order to resync old Input, you still possess TASer's critical thinking, so you may notice another mistake or unimplemented idea by the way.

      -

      Sometimes it's like a snowslide – as the trouble grows, so grows the thrill of all the discoveries. Many ingenious speedrun overtakes were made because of noticing a small improvement in the middle of the movie, which then forced TASer to re-record the remaining half of the movie (in order to resync it using traditional method) and stumble upon new discoveries in the process. And then these new tricks appear to be useful in the first level of the game! Since the game has single engine, a trick that works in one level may be applied in another, where the similar conditions are met. Even if some conditions aren't met, sometimes you can create them by losing something less important... So, in the end, as the movie gets rewritten many times, the initial small improvement turns into large-scale progress.

      -

      You should learn not to feel sorry when you have to throw away results of your hard work. In TASing you're expected to reconsider even polished parts of the movie from time to time. The traditional method of TASing quickly makes you accustomed to inevitable losses of time, because any inattention or slipped finger requires you to rerecord part of current segment. Taseditor averts such minor losses, but doesn't change the fact that you have to retry new approaches after finding new optimality factors.

      -

      For example, when polishing the Input near the end of World 1-3, you've suddenly found a new trick allowing you to get a mushroom, and it also appears to work in the World 1-1. Now you have to redo both 1-1, 1-3 and even 1-2, because you now play World 1-2 with big Mario. Of course, TASing the same levels second time is easier, but the fact of wasted time may dispirit you at first. Sometimes it may seem that fixing the old mistake is not worth spending additional time. At this point you'd better stop thinking too much and just choose one of the two options – either immediately start fixing, or postpone it for an indefinite period (and leave the Marker with a note describing the issue). If at the end of the project you accumulate a critical mass of such postponed plans, the movie should be called a "test run" and probably also published, at least as a WIP (work in progress). Then take some considerable rest until you feel like redoing the TAS (making an improvement).

      -


      -

      Despite all the difficulties, TASing can bring enjoyment both to viewers and authors. TASes are made by people who consider this kind of work to be balanced (paid off) by the excitement from intermediate and final results. In many senses TASing is similar to a special meta-videogame with a unique gameplay mechanic. And until games bring fun, people play them no matter how hardcore they are.

      -


      -

      In the next chapter: descriptions of Input optimization methods.

      -


      -
      - - - -

      PRACTICE: Watch the imperfect playthrough of the 1st level that you made in previous chapter, and divide it into segments using Markers and your own discretion. If the movie is rather long, no need to structure it all, you just have to feel the principles.

      -

      Estimated time: 5-10 minutes.

      -
      -
      -


      -


      -


      -


      -


      -

      -

      Created with the Personal Edition of HelpNDoc: Free help authoring environment

      -
      - - - - + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      3. TASing Process

      + +
      + +

      +

      TASing Process

      +


      +


      +

      TASing is about striving for an absolute perfectness. For TASers, a game is more than just an amusement, it's an interesting and complex task.

      +

      People enjoy solving creative tasks, because it allows them to express their individuality and improve various skills. However, complicated tasks require both inventiveness and methodicalness. This Manual describes dry and methodical side of TASing, as for inventiveness – you'll have to show it yourself in real setting.

      +

      In general, to create a perfect (or very close to perfect) playthrough of the game you have to record an imperfect walkthrough and then work on consecutive improvements of its separate parts. When every fragment of the movie is perfect, we may consider the whole TAS to be perfect as well.

      +

      The concentration of efforts on small segments of the movie is the key to success. Every working segment has to be large enough to represent an adequate subtask, but small enough to make the task simple.

      +

      Without such structuring an effective and comfortable TASing would not be possible. There's too many factors affecting the final result of the game, and some of those factors append or contradict each other. Human memory is not enough to keep and calculate all interconnections of the game factors within a large segment of the playthrough. Therefore, when TASers deal with long play sessions, they aren't different from regular players who are carried by the temptation to use the first observations as a base for making decisions. But regular players can get away with such carefree approach, while TASers would end up with a clearly imperfect walkthrough.

      +

      Thus real TASing implies that segments are small. Much smaller than a single level of a typical videogame. The whole process of TASing may be portrayed like this: a man watches the recording of his own unfinished playthrough of the game, selects a small piece of the movie and throws all forces into improving it, then selects another piece and so on until the end of the game.

      +

      Of course, it's an incomplete picture, because besides the movie editing TASers also research and experiment with the game (to expose hidden factors) and do many other things. But that's beyond the scope of this Guide.

      +

      The skill of choosing adequate segments comes with experience. Many TASers don't even think what makes them spontaneously focus on a segment of the game and unconsciously limit the beginning and the end of current work. Some believe that they simply record the movie frame-by-frame in succession, but if you watch it from outside you can note that those repeated rerecords occur within a window of 20-200 frames, and the window goes forward the movie by making jumps (the end of previous segment becomes the beginning of next segment). Consider watching live stream videos of TASing, and you'll see certain regularities in handling savestates.

      +

      Here we'll try to analyze the behavior, in order to learn how to define current segment limits sensibly. And then practical TASing will make you do it mechanically.

      +


      +

      An adequate segment (subtask) is supposed to give TASer a consistent goal and simple means to reach it.

      +

      The goal of a segment playthrough is usually to achieve certain in-game event. For example, the goal of playing through the whole game is the event when "THE END" text appears on the screen. The goal of one level can be such event as "the value of the level counter in RAM was increased" or simply "the screen faded at the end of current level". And the goal of a small segment may be something like "the character successfully landed on the other side of the pit". These intermediate goals are defined by the context.

      +

      Based on the goal, TASer defines the optimality criterion in mind. The criterion is the rule which lets you compare any two versions of playing through the current segment of the game. When you're TASing, it's not enough to simply reach the goal, you have to try many approaches to reaching it, and then choose the best approach of all. For example, in a speedrun the best approach to playing a segment is usually the one in which the target event occurs as early as possible. E.g. if the 1st approach to playing the segment made the event occur at frame 350, and the 2nd approach made it appear at frame 340, then the 2nd approach is better than the 1st, and the final movie should contain exactly the 2nd approach.

      +

      There's a lot of means for reaching the target event. In theory, any gameplay aspect (including those not planned by developers) may help or impede the progress in some way. So, to cope with this vague multitude of possibilities you should regard all aspects of the game as optimality factors.

      +

      +

      An optimality factor is an aspect of the game that directly affects optimality of playing current segment. The word "directly" implies a monotonous dependence of outcome from applying the factor. For example, on this picture there's no monotonous dependence between the distance to finish and the duration of holding Right. Pressing the same R button either makes Mario be closer to the finish, or moves him away, depending on his position.

      +

      When people perceive such segment in a whole, it's difficult to guess the best moment to release the R button, when to press the L button and so on. So, in order to simplify the understanding of complex dependencies (and thus reveal factors), such segments should be broken into several subsegments.

      +

      Correct statement of question usually cuts off many irrelevant possibilities. For example, regular player could wait until the difficult enemy character walks away, but in a speedrun such tactic is not considered.

      +

      Thus even in an open-world game TASer is left with a limited set of useful actions and in-game indicators that must be followed while polishing one segment. And the less the segment is, the more limited is this set, so it's easier to find an ideal sequence of actions by going over combinations of factors.

      +

      On the other hand, the less the segment is, the less its goal intersects with the final goal of the TAS. The final goal is to make perfect walkthrough, e.g. the fastest in the world (which means the frame counter at the end of the movie should be as low as possible). But in terms of every specific segment the goal may be completely different, sometimes even opposite (for example, to stay in bonus stage as long as possible, which then grants time saving at another point of the game). That's why in very small segments the optimality criterion is not used, and playing such micro-segment is only evaluated as a part of a full-fledged segment.

      +

      For example, when your character is jumping over a pit and shooting enemies at the same time, every bullet release can be considered a separate subsegment (so it becomes easy to isolate such factors as "recharge timer", "max 3 bullets on screen" and so on). But then, when comparing approaches, you should compare different versions of jumping over the pit. Even if the 1st approach to jumping (which ends at the frame 350) allowed you to shoot two enemies and the 2nd approach (which ends at frame 340) allowed to shoot only single enemy, you are supposed to choose the 2nd approach, because the optimality criterion of the unbroken segment fits the final goal of the speedrun better.

      +

      While TASing you have to maintain an optimal balance between the necessity to decrease segments in order to grasp factors and the need to increase them in order to use a relevant criterion. This skill comes with time, so don't sweat it and just rely on your intuition.

      +


      +
      + + + + +
      +

      Let's have an example when the segment is too large. In a Super Mario Bros speedrun you are expected to reach the end of World 1-1 as fast as possible, which means you have to maximize the X coordinate of the character moving from left to right. The basic premise is that at the beginning of the level the X value equals zero and at the end of the level it is one thousand. Using gamepad buttons you can influence the coordinate in various ways.

      +

      If we take the whole level from the moment X = 0 to the event X = 1000 as our working segment, we can immediately see the optimality criterion (the best approach will be the one with minimal value of the frame counter when X >= 1000), but we can't see definite factors. How exactly we're supposed to press buttons to get the X = 1000 within minimal number of frames? Well, we can apply a regular player's logic and intuition. When we press the R button, the X coordinate usually increases, and with the L button it decreases. So the most obvious decision is to hold the R button and see how many frames is needed to grow the value of X to one thousand. When testing such approach in emulator, it appears that Mario is hampered by obstacles and the X coordinate does not grow, even though the R button is held. This way a new factor comes to light – the need to jump over obstacles and pits. Using the A button Mario eventually reaches the X = 1000 event, and the optimality criterion can eliminate all alternative playthroughs where the A button presses were ill-timed (e.g. where Mario stumbled over edges of pipes, the frame counter at the end of the segment was higher).

      +

      Now the player (or rather, TASer who is stuck in player's mindset) may think that all factors are applied and the segment is perfect. But it isn't. Super Mario Bros has somewhat complex physics engine. The X coordinate is influenced by current horizontal speed, and speed is influenced by acceleration. Acceleration is affected by the B button, skidding, Mario's direction and air-ground state. There are also teleporter pipes and useful glitches like the "flagpole glitch" and so on. A lot of things to bear in mind. But, according to certain research, human working memory can only store about 7 objects, thus some factors inevitably slip away when you're editing Input on large segment. You'd better shrink the segment to such a scale which reveals factors individually or in a small group.

      +

      If we focus on the segment from X = 0 to X = 100, the optimality criterion will be the same, but now it also becomes obvious that in the first half of the segment Mario runs slower, and in the second half he runs with constant speed which can be considered maximum. This way you begin to appreciate the acceleration factor, so you add the RAM address to Memory Watch and start analyzing possible ways to influence the acceleration. After some experiments with turning and jumping you can discover more factors. As a result, you're going to find an intricate combination of R, L, B and A buttonpresses that makes the event X = 100 occur faster than simply holding R and B. And even if the new playthrough of the segment is only several frames faster than old, it's much closer to perfectness.

      +
      +
      +


      +
      + + + + +
      +

      Now let's take a look at another extreme. When segment is too small, its optimality criterion may contradict the final goal of the TAS.

      +

      First, if you get carried away by maximizing speed and acceleration in equal intervals between every next hundred of pixels, you may forget about the shortcut pipe, because diving into pipes resets speed value to zero, which contradicts with the goal of current segment. In short term the diving factor is disadvantageous for a speedrunner, and its long-term profit may be overlooked when you're busy with habitual actions.

      +

      +

      In this case the segment was chosen without much foresight, and as a consequence it sprouted wrong criterion of optimality ("the frame counter at the event X = 200 must be minimal"). Instead, the segment should end at the moment when any Down button press starts diving animation.

      +

      Of course such mistakes are often noticed when replaying finished movie on a fresh mind, but sometimes the situation is less obvious and is only revealed after publishing.

      +


      +

      Second, in the same SMB game after diving into the pipe (World 1-1) you have to reach the exit to the right. It may seem necessary to start maximizing speed from the very beginning. But as you may see in the picture, within first dozen of frames it's better to hold the L button instead of R, so that Mario lands slightly aloof from the wall that needs to be jumped over. If you hold R too early, Mario will land close to the wall and will have to jump vertically, thus losing gathered speed.

      +

      This peculiarity is not so obvious when you choose optimizing the segment from the event Mario appears to the Mario lands event. The optimality criterion of such small segment will direct you to wrong sequence of buttonpresses.

      +

      Here you should choose the segment from the frame when Mario appears to the moment of overcoming the corner of the wall.

      +

      Unfortunately, even experienced TASers not always choose correct limits right away. Sometimes you have to rethink and redo, throw away results of many tests and change the scale of the segment, play the same part of the game many times again.

      +
      +
      +


      +

      As you might have noticed, this document avoids measuring segments in real frames of the movie. Because actual size of segment varies from game to game and from stage to stage. Some parts of the game contain so little possibilities that they can last for more than a thousand of frames and still be easy to play and replay. By the way, some segments don't even need to be played more than once, since they are so simple that any successful playthrough is optimal (for instance, watching unskippable cutscenes between levels). And on the contrary, some stages of the game are supersaturated with events and factors, so you are going to sweat even over a dozen of frames.

      +

      Experienced TASers regard every segment individually (although they don't think too much about it). It's bad idea to choose the next segment by the same principle as previous, this would only work well in extremely repetitive games.

      +

      If you want, you can limit the end of current segment by a fixed frame number (e.g. set the goal to maximize the X coordinate value when the frame counter = 200). But usually it's more convenient to associate the end with some small frontier of the game (like passing over a trap or defeating another enemy) – then the goal itself is going to suggest you basic means for reaching it. The task "touch a flower as fast as possible" sounds more natural (for a gamer) than the task "at the frame 300 become as close to the flower as possible".

      +

      In the vast majority of video games the gameplay divides into "rooms", "enemy waves" and "traps", which are always separated by short periods of relaxation. Even in constantly scrolling and open-world games the level design ensures that there are intense moments and filler intervals between them. The truth is, game designers also structure player's task into subtasks, and in some cases TASer can even borrow the prepared segmentation. Just don't forget to critically assess it and subdivide into more subsegments when needed. Though, such subdivision will naturally take place in the process of editing Input on a excessively large segment. So TASing doesn't always require intense intellectual efforts. If you're skillful and smart, most of time you can just go with the flow and enjoy TASing no less than conventional gaming.

      +

      All this can be compared to how writers divide their books into chapters (game levels), and chapters into paragraphs and sentences (segments) in order to aid with comfortable reading and comprehending author's ideas. A regular reader (player) is satisfied with the author's subdivision, but a literary critic (TASer) needs to be able to "read between lines" by dividing text his own way.

      +

      For example, in Super Mario Bros every group of enemies is separated by a quiet space which doesn't require any skills, and it can be light-heartedly ran over or jumped over while holding Right (granted that Mario speed is already at maximum). So you don't even need TAS tools to be perfect at these moments. These intervals are the most suitable place to set a goal – if you mark an end of the segment at such place, the optimality criterion won't contradict with final goal of TAS for sure. And usually these moments occur often enough so the segment between them is of an acceptable size.

      +


      +
      +


      +

      The division to segments was always present in TASing, but Taseditor allows to accentuate the process visually. Here you can mark the beginning and the end of a segment using Markers or Bookmarks. Thanks to the visible boundaries you won't be distracted onto adjacent Input and can focus on analyzing only closest factors.

      +

      The frame of current segment beginning is usually chosen when watching a test playthrough of the current segment. When recording or watching such playthrough you already pick one or two key factors of optimality. So it's only logical to start the segment at the moment when these factors join into force or dramatically change the behavior. For example, at the beginning of every level you usually start a new segment, because that's the point where you regain the ability to move forward (after the cutscene between levels ends). So it's wise to set a Marker or a Bookmark at the beginning of every level, thus marking both the level boundary and the beginning of current work segment.

      +

      And if in the process of optimizing the segment you reveal some factors that join into force earlier than current beginning of the segment, you can always adjust the chosen boundaries of the segment, or break it in two subsegments.

      +

      The ending frame of current segment is more mobile than the frame of beginning. When you define your goal (e.g. to make the X coordinate reach the value of 50) you can mark the end of current segment by setting a Marker/Bookmark to the frame where current imperfect playthrough accomplishes this goal. Then by polishing the Input you try to reach the goal (X = 50) at an earlier frame. And if in the process of modifying and testing a new Input you discover that the goal indeed can be reached earlier, you move the closing Marker/Bookmark up (to the frame of the improved end). After that you continue testing new approaches, searching for even better one until you don't feel any more potential. In traditional TASing this is exactly how the main Bookmark (storing current best playthrough of the segment) gradually moves up.

      +

      Well, sometimes you can indulge in laziness and avoid marking the end of current segment, instead you just keep the goal in mind and remember the number of the frame where the target event occurs in the best case so far. Such behavior is reasonable when the segment is very simple and you don't plan to redo it many times.

      +

      Moreover, in many platformer games where the player character has constant running speed most of segments can be played optimally from the first try (you just have to hold the Right button and maybe jump over trivial obstacles). So if you don't see any obvious mistakes and don't intend to search for hidden flaws, you may as well skip the segment shaping, just proceed to next segment right away. Such simple games are especially suitable for newbie TASers, because TASing them is very similar to casual playing through videogames using savestates (when you only revise the most obvious mistakes, like falling into a pit, and ignore non-fatal roughness).

      +

      But in complex TASes, where the mind is occupied with many optimality factors, you shouldn't hurry. To make your thought process more precise, you'd better be perfectly aware of current segment boundaries. So mark the beginning of any difficult segment with a Marker, and mark the end by setting a Bookmark every time you find an improvement (use one and the same slot). Since it's not easy to find an improvement when dealing with difficult tasks, don't expect you'll have to re-set the Bookmark too often.

      +

      When you're confident you've found perfect solution of the segment, move to the next segment. Don't remove old Markers, since they may be useful in future, in case you begin doubting the perfectness of your decisions (e.g. after finding a new trick). The logic of movie dividing will most likely remain the same even after finding the new factor (the trick).

      +

      Also, if in the middle of optimization process you become confident you've found perfect Input for the first half (or a third) of current segment, you can divide the segment in two and focus on optimizing the remaining section. Such situations often rise when the initially chosen segment was too large and its logical parts naturally emerged in the process of editing the Input.

      +


      +

      So, if you don't like to keep things organized, you can avoid Markers and Bookmarks whatsoever, working mostly in terms of fuzzy in-game concepts and imagining segments as some emotional sequences of events. Unfortunately, the data about fuzzy goals also occupies part of human working memory, and as a result you won't have enough resources to keep all optimality factors in mind. And you won't even notice how you've overlooked a multitude of possibilities.

      +

      On the contrary, if you like to keep an order, it's recommended to accompany Markers with text Notes, either before, or during, or after the optimization of the current segment. For example, make up a name for the segment or put a tag. This way you document the development of the TAS during actual TASing, give an objective meaning to the Input appearing in the process. This is especially useful when TASing in co-authorship. But even when working alone, you may notice the documentation from previous levels motivates you to carry on. It only takes seconds to type that kind of texts, and then it helps not to abandon the project.

      +

      Notes also help to better unlock the potential of tricks and bugs of the game. By writing the text you actually formalize your knowledge about the described phenomenon. When the essence of the trick is kept in your mind, you may think that you already know everything about it, and that your current TAS uses the trick the best way possible. But when you construct an objective model (a verbal description of the trick) you often find its new sides.

      +

      It's not uncommon for TASVideos.org to see how one TASer read the description of a trick in the submission text written by another TASer and found a way to use the trick better than original author. There were also cases when author himself reads his recent submission, facepalms and urgently records an improvement.

      +


      +
      +


      +

      Making a perfect TAS can take anything from several days to several years, depending on complexity of the chosen game. Most of that time is spent on finding an ideal sequence of buttonpresses for every segment.

      +

      Often it seems right away that current Input is already the best possible. But usually it's not so, especially if you make the conclusion judging by the external image of the emulated game instead of its internal state (Memory Watch). So it's always reasonable to suppose that current result is not perfect. If you don't see any mistakes or potential improvements at the moment, try to watch the segment together with several previous segments (e.g. watch the last half a minute of your movie), because it's possible that previous segments contain some unregistered optimality factors that have an effect on current segment. And if you still don't get any ideas, consider moving to next segment, but don't completely refuse further attempts to criticize and improve finished segments.

      +

      Rewatch the finished part of your movie from time to time – either from the very beginning, or from the beginning of current level – and try to notice imperfections. Taseditor allows to edit Input in any part of the movie while the movie is still playing, so you can quickly test any spontaneous idea right when it comes to your mind. If the new idea appears to be unsuccessful, just undo latest changes or load the Bookmark containing the last stable state of the movie.

      +

      And if the new idea in fact improves you TAS, after a joyful anticipation you have to ensure that all the following segments of Input sync to the game (because implementing the idea has changed the flow of the game). Most of time it's not necessary to redo all the following Input. Usually you only have to delete or insert a few frames (thus shifting all following segments up or down), or modify several segments between the place of implementing the new idea and the nearest checkpoint (the end of current level, etc). Checkpoints usually reset many in-game properties to default value (e.g. they require you to walk over specific platform, thus equalizing the Y coordinate), so after the checkpoint you old Input will sync with new timeline of the game once you adjust it to match the flow of game events.

      +

      Anyway, even in cases when you have to redo considerable parts of the movie, resyincing is much easier than TASing from zero ground, because now you know the best approach for each segment and only have to match your previous results. And sometimes you can even excel them, because, when you're doing these forced modifications in order to resync old Input, you still possess TASer's critical thinking, so you may notice another mistake or unimplemented idea by the way.

      +

      Sometimes it's like a snowslide – as the trouble grows, so grows the thrill of all the discoveries. Many ingenious speedrun overtakes were made because of noticing a small improvement in the middle of the movie, which then forced TASer to re-record the remaining half of the movie (in order to resync it using traditional method) and stumble upon new discoveries in the process. And then these new tricks appear to be useful in the first level of the game! Since the game has single engine, a trick that works in one level may be applied in another, where the similar conditions are met. Even if some conditions aren't met, sometimes you can create them by losing something less important... So, in the end, as the movie gets rewritten many times, the initial small improvement turns into large-scale progress.

      +

      You should learn not to feel sorry when you have to throw away results of your hard work. In TASing you're expected to reconsider even polished parts of the movie from time to time. The traditional method of TASing quickly makes you accustomed to inevitable losses of time, because any inattention or slipped finger requires you to rerecord part of current segment. Taseditor averts such minor losses, but doesn't change the fact that you have to retry new approaches after finding new optimality factors.

      +

      For example, when polishing the Input near the end of World 1-3, you've suddenly found a new trick allowing you to get a mushroom, and it also appears to work in the World 1-1. Now you have to redo both 1-1, 1-3 and even 1-2, because you now play World 1-2 with big Mario. Of course, TASing the same levels second time is easier, but the fact of wasted time may dispirit you at first. Sometimes it may seem that fixing the old mistake is not worth spending additional time. At this point you'd better stop thinking too much and just choose one of the two options – either immediately start fixing, or postpone it for an indefinite period (and leave the Marker with a note describing the issue). If at the end of the project you accumulate a critical mass of such postponed plans, the movie should be called a "test run" and probably also published, at least as a WIP (work in progress). Then take some considerable rest until you feel like redoing the TAS (making an improvement).

      +


      +

      Despite all the difficulties, TASing can bring enjoyment both to viewers and authors. TASes are made by people who consider this kind of work to be balanced (paid off) by the excitement from intermediate and final results. In many senses TASing is similar to a special meta-videogame with a unique gameplay mechanic. And until games bring fun, people play them no matter how hardcore they are.

      +


      +

      In the next chapter: descriptions of Input optimization methods.

      +


      +
      + + + + +
      +

      PRACTICE: Watch the imperfect playthrough of the 1st level that you made in previous chapter, and divide it into segments using Markers and your own discretion. If the movie is rather long, no need to structure it all, you just have to feel the principles.

      +

      Estimated time: 5-10 minutes.

      +
      +
      +


      +


      +


      +


      +


      +

      +

      Created with the Personal Edition of HelpNDoc: Create iPhone web-based documentation

      + +
      + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/taseditor/Title.html b/web/help/taseditor/Title.html index f54daca8..0c604355 100644 --- a/web/help/taseditor/Title.html +++ b/web/help/taseditor/Title.html @@ -1,135 +1,344 @@ - - + + + + + - Title - - - - - - - - - - + + + + + + + + Title + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      Title

      - -
      -
      - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Title

      + +
      +

      -


      -


      -

      TAS Editor 1.01

      -


      -


      -

      Welcome to the TAS Editor Manual!

      -


      -
      - - - +


      +


      +

      TAS Editor 1.01

      +


      +


      +

      Welcome to the TAS Editor Manual!

      +


      +
      +

      Taseditor is an Integrated development environment dedicated to TASing.

      -

      Playing videogames in Taseditor resembles both interactive programming and drawing notes by mouse in a music editor.

      -
      + + +
      +

      Taseditor is an Integrated development environment dedicated to TASing.

      +

      Playing videogames in Taseditor resembles both interactive programming and drawing notes by mouse in a music editor.

      +
      -


      -
      - - - - - - - - - - - - - - - +


      +
      +

      Beginner's Guide

      -

      Reference

      -

      TAS Editor Inside

      -

      If you're seeing the Manual for the first time, please study this whole course

      -

      Look here when you need to know comprehensive specifications about limits and possibilities of TAS Editor

      -

      Read these docs when you wish to learn details of the system

      -

      Introduction

      -

      Program Interface

      -

      TASing Process

      -

      TASing Methodology

      -

      Program Customization

      -

      Advanced Features

      -

      Glossary

      -

      Controls

      -

      Navigation

      -

      Operations

      -

      Lua API

      -

      FAQ

      -

      Speedrunning Synopsis

      -

      Ideas

      -

      Implementation

      -

      Mistake-proofing

      -

      FM3 format

      -
      + + + + + + + + + + + + + + +
      +

      Beginner's Guide

      +
      +

      Reference

      +
      +

      TAS Editor Inside

      +
      +

      If you're seeing the Manual for the first time, please study this whole course

      +
      +

      Look here when you need to know comprehensive specifications about limits and possibilities of TAS Editor

      +
      +

      Read these docs when you wish to learn details of the system

      +
      +

      Introduction

      +

      Program Interface

      +

      TASing Process

      +

      TASing Methodology

      +

      Program Customization

      +

      Advanced Features

      +
      +

      Glossary

      +

      Controls

      +

      Navigation

      +

      Operations

      +

      Lua API

      +

      FAQ

      +

      Speedrunning Synopsis

      +
      +

      Ideas

      +

      Implementation

      +

      Mistake-proofing

      +

      FM3 format

      +
      -


      -


      -


      -

      Author of TAS Editor v1.01: AnS

      -

      Assistance in testing: feos

      -


      -

      Author of this Manual: AnS

      -

      English translation: AnS, feos

      -


      -





      +

      Author of TAS Editor v1.01: AnS

      +

      Assistance in testing: feos

      +


      +

      Author of this Manual: AnS

      +

      English translation: AnS, feos

      +


      +


      +


      +


      +


      -

      Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

      -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/Toolbox.html b/web/help/taseditor/Toolbox.html index 0a915d8d..ae51a846 100644 --- a/web/help/taseditor/Toolbox.html +++ b/web/help/taseditor/Toolbox.html @@ -1,278 +1,465 @@ - - + + + + + - 2.2. Toolbox - - - - - - - - - - + + + + + + + + 2.2. Toolbox + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      2.2. Toolbox

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      2.2. Toolbox

      + +
      +

      -

      Toolbox

      -


      -

      -


      -

      The Toolbox consists of 7 sections:

      -


      -
        -
      • Playback
      • -
      • Recorder
      • -
      • Splicer
      • -
      • Lua
      • -
      • Bookmarks
      • -
      • History
      • -
      • Selection cursor navigation buttons
      • +

        Toolbox

        +


        +

        +


        +

        The Toolbox consists of 7 sections:

        +


        + -


        -
        -

        -

        -

        -

        The top section is allotted to the Playback controls. The Playback is the component of Taseditor dedicated to handle game emulation: keep it paused, replay in any direction, rewind to desired frame and so on. It allows to treat video games as straightforwardly as if they were regular video recordings, disregarding the interactivity element inherent to them.

        -

        There are 5 buttons at the top of the window.

        -

        The "||" button (pause/resume) is simple graphical analog of the Pause Emulation hotkey. When you click it, the game emulation either pauses or resumes. However, if your mouse has a middle button, it's easier to press it instead of clicking the "||" button, in this case you won't need to move the mouse cursor to the Playback section.

        -

        The ">" button (step forward / advance 1 frame) moves the light-blue cursor 1 frame down, forcing FCEUX to emulate one frame if necessary. You can either click that button or click and hold it to make several steps forward. This button's keyboard analog is Shift + Down. If your mouse has a wheel, it's easier to hold the right mouse button and scroll the wheel 1 step down instead of using the ">" button.

        -

        The "<" button (step back / rewind 1 frame) moves the Playback cursor 1 frame up, displaying the previous frame's events in the FCEUX window. You can hold the button as well, when you wish to go several frames back. This button has its hotkey Frame Rewind (mapped to Backspace key by default), and has a keyboard analog: Shift + Up. If your mouse has a wheel, it's easier to hold the right mouse button and scroll the wheel 1 step up instead of using "<" button.

        -

        The "<<" button (fast rewind) also moves the Playback cursor back, just not by 1 frame but by multiple frames at once. This button moves the light-blue cursor to the frame where the nearest upper Marker is located. In the above picture, if you press the "<<", the light-blue cursor will jump to frame 12 (where the Marker 1 is set). Using this button you may quickly go back to the beginning of the edited segment or to any other past moment of the movie. The keyboard analog for this button is Shift + Page Up. You can also hold it – the light-blue cursor will rapidly jump on Markers up in the Piano Roll, and in the meantime you can look for the desired fragment of the movie by watching FCEUX screen.

        -

        The ">>" button (fast forward) jumps on Markers forward. In the above picture, if you press the ">>", the light-blue cursor will jump to frame 22 (where the Marker 2 is located). With this button you can rapidly skip to the game events forward in the movie. But in case the next Marker is out of the Greenzone range, emulator would need some time to process the unknown frames, so such jump may take some time. This button's keyboard analog is Shift + Page Down. You can click and hold this button as well.

        -

        As an experiment, try to make a test movie of about 1000 frames in size and set a dozen of Markers, one per every 30-50 frames. Then hold Shift and tap some Page Up / Page Down keys to feel the convenience of the fast scrolling. Alternatively you can roll the mouse wheel while holding the Shift key.

        -

        -

        -

        Below these 5 buttons you can see a progress bar and three checkboxes.

        -

        The Progress bar helps to estimate the time needed for Playback seeking. Immediate jumps to any frame are only possible after FCEUX emulated the game up to the target frame by applying your movie as a game Input to get the actual game state for the frame. After the actual game state was rendered at least once, it is saved into the Greenzone, so next time the emulator can instantly jump to that frame, granted that Input above the frame didn't change. If the Input was changed, a new emulation attempt is required, because even the smallest change in buttonpresses may cause serious changes in the gameplay chronology. Thus after every such change the Greenzone is automatically truncated, removing the data of all those frames that might be affected by the new Input. These frames must be emulated again, and it takes some time.

        -

        So, when you send the Playback cursor to a frame far from the Greenzone, instead of immediate jump the light-blue cursor starts seeking to that frame. A shadow of the light-blue cursor will be blinking at the target line of the Piano Roll, and the game images on the FCEUX screen will rapidly change as the Playback cursor runs to the target.

        -

        In this case you'll have to wait. The seek time depends on the distance between the target frame and the end of the Greenzone, on your computer power and a few other factors. The progress bar helps to estimate the waiting time. If you don't want to wait, left-click on the progress bar (in addition to being an indicator, it's also a button) or use the Cancel Seeking hotkey (Esc by default). Then the target frame will quit blinking, the light-blue cursor will stop and the emulation will be paused.

        -

        While Playback is seeking you may change the target by clicking on the desired frame row in the icons column of the Piano Roll. If you pause the emulator during seeking, the light-blue cursor will freeze and the target frame blinking will slow down, but the seeking won't be cancelled – when you unpause, the Playback cursor will continue running to the target and stop automatically after hitting it.

        -

        This Progress bar is also used when loading and saving Taseditor project files to disk.

        -

        -

        -

        The "Turbo seek" checkbox allows to change the seeking speed. When the Turbo is on, FCEUX emulates the game on the highest speed possible, reducing the seeking time tenfold. So, if you seek to a distant frame, check that option. But during the TASing process its often necessary to see all the intermediate frames, not just the last one. In such cases you should uncheck the checkbox and maybe even slow down the emulation with the - and = hotkeys to ensure you're not missing any important detail of the gameplay.

        -


        -

        The "Follow cursor" checkbox forces the Piano Roll to follow the movement of the Playback cursor and autoscroll the view so that the light-blue cursor is always visible. This allows you to observe the Input played back when the emulator is unpaused. But when you edit the movie you should uncheck this option to prevent the Piano Roll from running away from the edited spot.

        -


        -

        The "Auto-restore last position" checkbox makes the Playback automatically start seeking when the Playback cursor was moved back by the Greenzone. Every time you change an Input, the Greenzone is truncated after the first changed frame, forgetting old events that became irrelevant after that change. The Playback cursor must always be inside the Greenzone, so it steps back along with it. With the auto-restore checkbox you can instantly see new events on these frames. When the checkbox is checked, any Input modification triggers the replaying of the changed segment, helping you to compare different scenarios of the game events.

        -

        Thanks to auto-restore, TASers can focus on Input editing and rapidly go over many approaches to playing current segment of the movie. This method of TASing will be described later.

        -


        -
        -

        -

        -

        -

        Below the Playback you can find the Recorder section. The Recorder is used to record buttons Input from keyboard (or gamepad) into the movie, just like in regular playing using any emulator.

        -


        -

        The "Recording" checkbox turns the Recording mode on and off. Before you start recording any physical keypresses, make sure the Playback cursor is on the frame you want to record from. Then either press the "Toggle Read-only" hotkey (Q key by default), or click the Recording checkbox. The word "Recording" will appear in the TAS Editor window caption, and the message "Movie is now Read+Write" will appear on the FCEUX screen. Now you can either unpause the emulator and play the game normally, or type the buttons frame-by-frame using the Frame Advance hotkey. As the playback goes forward, the movie will fill with the data on the buttons you press.

        -

        You may rerecord the same segment of the movie multiple times, overwriting the old button log with new buttonpresses data. If you don't like how a segment was played (e.g. the character fell into a pit), put the Playback cursor before the frame where you made wrong buttonpresses (e.g. the A button was pressed too late) and resume Recording, this time pressing buttons properly.

        -

        When the segment is ready, turn the Recording mode off to prevent accidental erasing of the Input when replaying the movie. Uncheck the checkbox by mouse click or via the hotkey. When TASing in Taseditor, the Recording checkbox is usually unchecked, because direct Input editing is preferred to Recording.

        -

        It's recommended to rationally combine the Recorder features with those of the Piano Roll. For long and easy segments of the game it may be convenient to record buttonpresses from the keyboard or a handy USB-gamepad, but for small dislocated edits the mouse is way better.

        -

        -

        -

        The "Superimpose" checkbox in the Recorder section allows to combine the existing Input with the newly recorded data on the same segment of the movie. For example, you can draw the R buttonpresses on rather long segment with a single mouse stroke, to make the character run right. Then you can enable the "Superimpose" option, turn on Recording and play the game by pressing only jump and shoot buttons, without the need to hold Right. The character in the game will still run right, jumping and shooting on command.

        -

        Unlike other checkboxes, the "Superimpose" option has three possible states. In addition to "enabled" and "disabled" it can also be in an interim state between these two. The third state works like this: when the player presses some gamepad buttons during Recording, these buttons are recorded in place of old Input. But if the player presses no buttons during Recording, the old Input on these frames is not overwritten.

        -

        -

        -

        The "Use pattern" checkbox applies current pattern to the process of buttons Recording. The name of the current pattern can be seen in the upper right corner of TAS Editor window (the last item of the main menu). If you click this menu item, a pop-down menu will appear, allowing you to choose another pattern from the list.

        -

        Patterns are used to speed up the process of entering monotonous buttonpresses and releases. For example, when you need to shoot at maximum rate (that is, alternate 1 frame of pressing B and 1 frame when B is released), you can just choose the "Alternating (1010...)" pattern and hold the B button without caring about manual mashing. Thanks to the pattern, the B buttonpresses will be recorded only for every other frame.

        -

        -

        -

        Besides the checkboxes the Recorder section also contains radio buttons that implement the multitracking feature.

        -

        Multitrack Recording greatly simplifies the traditional method of TASing games made for 2 or more players. Instead of pressing buttons of both gamepads at once, you can record a short segment of controlling the Player 1 and then record actions of Player 2 on the same segment of the movie.

        -

        By default the Recorder is set to recording "All" pads. You can choose a single pad by clicking the respective radio button ("1P", "2P", etc – the number of available gamepads depends on your project type). You can also use the "Switch current Multitracking mode" hotkey (W key by default). Now during the Recording the emulator will accept only the chosen player's buttonpresses, and the Piano Roll columns for other pads won't change even if you accidentally press another player's buttons.

        -


        -
        -

        -

        -

        -

        The Splicer section comes after the Recorder. It's dedicated to displaying the most necessary data used in non-linear editing of the movie.

        -

        Despite the similar sounding, editing TASes is totally different from using a non-linear video editing software, because Taseditor only allows you to edit Input, not the finished video footage (Output). The resulting video stream is built by the game itself.

        -

        In this section you can see the information on current Selection size: how many rows and columns are covered. With this info you can use the Selection as a measuring scale (ruler). E.g. to find the temporal distance between two in-game events, click the frame of the first event and stretch the Selection to the frame of another – all those frames will be selected, and in the Splicer section the message "Selection: N rows, M columns" will tell you the number of frames in question.

        -

        Also, here is the info about the Clipboard contents: whether it contains an Input that could be pasted to any place in the movie. When an Input is copied to the Clipboard, this line displays total amount of frames copied. The Clipboard data is stored independently of Taseditor, and it's kept there even after you close FCEUX, until some other application copies its own data to the Clipboard.

        -

        The "Splicer" section has no controls, because all Input splicing commands are kept in the Edit menu item and are assigned with accelerator keys. In actual TASing process it's recommended to use the keyboard combinations, because they're easy to remember and the working speed increases immensely.

        -

        -

        -

        The list of all Editing functions

        -


        -

        Basically, these are the standard functions of any text editor, but in Taseditor they can be applied to Input in the middle of emulation, which allows to analyze the results on the fly and flexibly tune your plans.

        -
          -
        • Copy (Ctrl + C) – copies the Input of all selected frames to the Clipboard.
        • -
        • Paste (Ctrl + V) – pastes the Clipboard contents into the movie, starting from the position of the Selection cursor. Old Input data on the frames is replaced by the new data, or combined together if the "Superimpose" option in Recorder section is checked.
        • -
        • Paste Insert (Ctrl + Shift + V) – expands the movie and inserts the Clipboard content at the position of the Selection cursor. Old movie data is shifted down.
        • -
        • Clear (Delete) – clears selected frames, removing all buttonpresses from them.
        • -
        • Cut (Ctrl + X) = Copy + Clear – copies Input from the selected movie segment and clears the segment.
        • -
        • Delete (Ctrl + Delete) – removes selected frames from the movie, shifting all the following frames up in their place. A handy way to move Input up.
        • -
        • Insert (Ctrl + Shift + Insert) – inserts blank frame into the movie before every selected frame, shifting existing Input down. A handy way to move Input down.
        • -
        • Clone (Ctrl + Insert) – similar to Insert, but instead of blank frames it inserts a copy of selected frames. Usually this is the preferred way of moving Input down.
        • -
        • Insert number of frames (Insert) – allows to insert any number of frames at the position of the Selection cursor. When you press the Insert key, a small window pops up and prompts you to enter the number of frames to insert. Type the number and click OK. If you change your mind, press Cancel (Esc) to hide the window.
        • -
        • Truncate – removes all frames of the movie, starting from the frame next to the Selection cursor. It's a rarely used function, so it has no hotkey, it's only available through the main menu or by the right-click.
        • +


          +
          +


          +

          +

          The top section is allotted to the Playback controls. The Playback is the component of Taseditor dedicated to handle game emulation: keep it paused, replay in any direction, rewind to desired frame and so on. It allows to treat video games as straightforwardly as if they were regular video recordings, disregarding the interactivity element inherent to them.

          +

          There are 5 buttons at the top of the window.

          +

          The "||" button (pause/resume) is simple graphical analog of the Pause Emulation hotkey. When you click it, the game emulation either pauses or resumes. However, if your mouse has a middle button, it's easier to press it instead of clicking the "||" button, in this case you won't need to move the mouse cursor to the Playback section.

          +

          The ">" button (step forward / advance 1 frame) moves the light-blue cursor 1 frame down, forcing FCEUX to emulate one frame if necessary. You can either click that button or click and hold it to make several steps forward. This button's keyboard analog is Shift + Down. If your mouse has a wheel, it's easier to hold the right mouse button and scroll the wheel 1 step down instead of using the ">" button.

          +

          The "<" button (step back / rewind 1 frame) moves the Playback cursor 1 frame up, displaying the previous frame's events in the FCEUX window. You can hold the button as well, when you wish to go several frames back. This button has its hotkey Frame Rewind (mapped to Backspace key by default), and has a keyboard analog: Shift + Up. If your mouse has a wheel, it's easier to hold the right mouse button and scroll the wheel 1 step up instead of using "<" button.

          +

          The "<<" button (fast rewind) also moves the Playback cursor back, just not by 1 frame but by multiple frames at once. This button moves the light-blue cursor to the frame where the nearest upper Marker is located. In the above picture, if you press the "<<", the light-blue cursor will jump to frame 12 (where the Marker 1 is set). Using this button you may quickly go back to the beginning of the edited segment or to any other past moment of the movie. The keyboard analog for this button is Shift + Page Up. You can also hold it – the light-blue cursor will rapidly jump on Markers up in the Piano Roll, and in the meantime you can look for the desired fragment of the movie by watching FCEUX screen.

          +

          The ">>" button (fast forward) jumps on Markers forward. In the above picture, if you press the ">>", the light-blue cursor will jump to frame 22 (where the Marker 2 is located). With this button you can rapidly skip to the game events forward in the movie. But in case the next Marker is out of the Greenzone range, emulator would need some time to process the unknown frames, so such jump may take some time. This button's keyboard analog is Shift + Page Down. You can click and hold this button as well.

          +

          As an experiment, try to make a test movie of about 1000 frames in size and set a dozen of Markers, one per every 30-50 frames. Then hold Shift and tap some Page Up / Page Down keys to feel the convenience of the fast scrolling. Alternatively you can roll the mouse wheel while holding the Shift key.

          +


          +

          Below these 5 buttons you can see a progress bar and three checkboxes.

          +

          The Progress bar helps to estimate the time needed for Playback seeking. Immediate jumps to any frame are only possible after FCEUX emulated the game up to the target frame by applying your movie as a game Input to get the actual game state for the frame. After the actual game state was rendered at least once, it is saved into the Greenzone, so next time the emulator can instantly jump to that frame, granted that Input above the frame didn't change. If the Input was changed, a new emulation attempt is required, because even the smallest change in buttonpresses may cause serious changes in the gameplay chronology. Thus after every such change the Greenzone is automatically truncated, removing the data of all those frames that might be affected by the new Input. These frames must be emulated again, and it takes some time.

          +

          So, when you send the Playback cursor to a frame far from the Greenzone, instead of immediate jump the light-blue cursor starts seeking to that frame. A shadow of the light-blue cursor will be blinking at the target line of the Piano Roll, and the game images on the FCEUX screen will rapidly change as the Playback cursor runs to the target.

          +

          In this case you'll have to wait. The seek time depends on the distance between the target frame and the end of the Greenzone, on your computer power and a few other factors. The progress bar helps to estimate the waiting time. If you don't want to wait, left-click on the progress bar (in addition to being an indicator, it's also a button) or use the Cancel Seeking hotkey (Esc by default). Then the target frame will quit blinking, the light-blue cursor will stop and the emulation will be paused.

          +

          While Playback is seeking you may change the target by clicking on the desired frame row in the icons column of the Piano Roll. If you pause the emulator during seeking, the light-blue cursor will freeze and the target frame blinking will slow down, but the seeking won't be cancelled – when you unpause, the Playback cursor will continue running to the target and stop automatically after hitting it.

          +

          This Progress bar is also used when loading and saving Taseditor project files to disk.

          +


          +

          The "Turbo seek" checkbox allows to change the seeking speed. When the Turbo is on, FCEUX emulates the game on the highest speed possible, reducing the seeking time tenfold. So, if you seek to a distant frame, check that option. But during the TASing process its often necessary to see all the intermediate frames, not just the last one. In such cases you should uncheck the checkbox and maybe even slow down the emulation with the - and = hotkeys to ensure you're not missing any important detail of the gameplay.

          +


          +

          The "Follow cursor" checkbox forces the Piano Roll to follow the movement of the Playback cursor and autoscroll the view so that the light-blue cursor is always visible. This allows you to observe the Input played back when the emulator is unpaused. But when you edit the movie you should uncheck this option to prevent the Piano Roll from running away from the edited spot.

          +


          +

          The "Auto-restore last position" checkbox makes the Playback automatically start seeking when the Playback cursor was moved back by the Greenzone. Every time you change an Input, the Greenzone is truncated after the first changed frame, forgetting old events that became irrelevant after that change. The Playback cursor must always be inside the Greenzone, so it steps back along with it. With the auto-restore checkbox you can instantly see new events on these frames. When the checkbox is checked, any Input modification triggers the replaying of the changed segment, helping you to compare different scenarios of the game events.

          +

          Thanks to auto-restore, TASers can focus on Input editing and rapidly go over many approaches to playing current segment of the movie. This method of TASing will be described later.

          +


          +
          +


          +

          +

          Below the Playback you can find the Recorder section. The Recorder is used to record buttons Input from keyboard (or gamepad) into the movie, just like in regular playing using any emulator.

          +


          +

          The "Recording" checkbox turns the Recording mode on and off. Before you start recording any physical keypresses, make sure the Playback cursor is on the frame you want to record from. Then either press the "Toggle Read-only" hotkey (Q key by default), or click the Recording checkbox. The word "Recording" will appear in the TAS Editor window caption, and the message "Movie is now Read+Write" will appear on the FCEUX screen. Now you can either unpause the emulator and play the game normally, or type the buttons frame-by-frame using the Frame Advance hotkey. As the playback goes forward, the movie will fill with the data on the buttons you press.

          +

          You may rerecord the same segment of the movie multiple times, overwriting the old button log with new buttonpresses data. If you don't like how a segment was played (e.g. the character fell into a pit), put the Playback cursor before the frame where you made wrong buttonpresses (e.g. the A button was pressed too late) and resume Recording, this time pressing buttons properly.

          +

          When the segment is ready, turn the Recording mode off to prevent accidental erasing of the Input when replaying the movie. Uncheck the checkbox by mouse click or via the hotkey. When TASing in Taseditor, the Recording checkbox is usually unchecked, because direct Input editing is preferred to Recording.

          +

          It's recommended to rationally combine the Recorder features with those of the Piano Roll. For long and easy segments of the game it may be convenient to record buttonpresses from the keyboard or a handy USB-gamepad, but for small dislocated edits the mouse is way better.

          +


          +

          The "Superimpose" checkbox in the Recorder section allows to combine the existing Input with the newly recorded data on the same segment of the movie. For example, you can draw the R buttonpresses on rather long segment with a single mouse stroke, to make the character run right. Then you can enable the "Superimpose" option, turn on Recording and play the game by pressing only jump and shoot buttons, without the need to hold Right. The character in the game will still run right, jumping and shooting on command.

          +

          Unlike other checkboxes, the "Superimpose" option has three possible states. In addition to "enabled" and "disabled" it can also be in an interim state between these two. The third state works like this: when the player presses some gamepad buttons during Recording, these buttons are recorded in place of old Input. But if the player presses no buttons during Recording, the old Input on these frames is not overwritten.

          +


          +

          The "Use pattern" checkbox applies current pattern to the process of buttons Recording. The name of the current pattern can be seen in the upper right corner of TAS Editor window (the last item of the main menu). If you click this menu item, a pop-down menu will appear, allowing you to choose another pattern from the list.

          +

          Patterns are used to speed up the process of entering monotonous buttonpresses and releases. For example, when you need to shoot at maximum rate (that is, alternate 1 frame of pressing B and 1 frame when B is released), you can just choose the "Alternating (1010...)" pattern and hold the B button without caring about manual mashing. Thanks to the pattern, the B buttonpresses will be recorded only for every other frame.

          +


          +

          Besides the checkboxes the Recorder section also contains radio buttons that implement the multitracking feature.

          +

          Multitrack Recording greatly simplifies the traditional method of TASing games made for 2 or more players. Instead of pressing buttons of both gamepads at once, you can record a short segment of controlling the Player 1 and then record actions of Player 2 on the same segment of the movie.

          +

          By default the Recorder is set to recording "All" pads. You can choose a single pad by clicking the respective radio button ("1P", "2P", etc – the number of available gamepads depends on your project type). You can also use the "Switch current Multitracking mode" hotkey (W key by default). Now during the Recording the emulator will accept only the chosen player's buttonpresses, and the Piano Roll columns for other pads won't change even if you accidentally press another player's buttons.

          +


          +
          +


          +

          +

          The Splicer section comes after the Recorder. It's dedicated to displaying the most necessary data used in non-linear editing of the movie.

          +

          Despite the similar sounding, editing TASes is totally different from using a non-linear video editing software, because Taseditor only allows you to edit Input, not the finished video footage (Output). The resulting video stream is built by the game itself.

          +

          In this section you can see the information on current Selection size: how many rows and columns are covered. With this info you can use the Selection as a measuring scale (ruler). E.g. to find the temporal distance between two in-game events, click the frame of the first event and stretch the Selection to the frame of another – all those frames will be selected, and in the Splicer section the message "Selection: N rows, M columns" will tell you the number of frames in question.

          +

          Also, here is the info about the Clipboard contents: whether it contains an Input that could be pasted to any place in the movie. When an Input is copied to the Clipboard, this line displays total amount of frames copied. The Clipboard data is stored independently of Taseditor, and it's kept there even after you close FCEUX, until some other application copies its own data to the Clipboard.

          +

          The "Splicer" section has no controls, because all Input splicing commands are kept in the Edit menu item and are assigned with accelerator keys. In actual TASing process it's recommended to use the keyboard combinations, because they're easy to remember and the working speed increases immensely.

          +


          +

          The list of all Editing functions

          +


          +

          Basically, these are the standard functions of any text editor, but in Taseditor they can be applied to Input in the middle of emulation, which allows to analyze the results on the fly and flexibly tune your plans.

          +
            +
          • Copy (Ctrl + C) – copies the Input of all selected frames to the Clipboard.
          • +
          • Paste (Ctrl + V) – pastes the Clipboard contents into the movie, starting from the position of the Selection cursor. Old Input data on the frames is replaced by the new data, or combined together if the "Superimpose" option in Recorder section is checked.
          • +
          • Paste Insert (Ctrl + Shift + V) – expands the movie and inserts the Clipboard content at the position of the Selection cursor. Old movie data is shifted down.
          • +
          • Clear (Delete) – clears selected frames, removing all buttonpresses from them.
          • +
          • Cut (Ctrl + X) = Copy + Clear – copies Input from the selected movie segment and clears the segment.
          • +
          • Delete (Ctrl + Delete) – removes selected frames from the movie, shifting all the following frames up in their place. A handy way to move Input up.
          • +
          • Insert (Ctrl + Shift + Insert) – inserts blank frame into the movie before every selected frame, shifting existing Input down. A handy way to move Input down.
          • +
          • Clone (Ctrl + Insert) – similar to Insert, but instead of blank frames it inserts a copy of selected frames. Usually this is the preferred way of moving Input down.
          • +
          • Insert number of frames (Insert) – allows to insert any number of frames at the position of the Selection cursor. When you press the Insert key, a small window pops up and prompts you to enter the number of frames to insert. Type the number and click OK. If you change your mind, press Cancel (Esc) to hide the window.
          • +
          • Truncate – removes all frames of the movie, starting from the frame next to the Selection cursor. It's a rarely used function, so it has no hotkey, it's only available through the main menu or by the right-click.
          -


          -

          When TASing in Taseditor you're going to most often use Ctrl + Delete (Delete Frames) and Ctrl + Insert (Clone Frames) to quickly move edited segments up/down in the frame list, thus performing certain in-game actions sooner or later.

          -

          Unlike FCEUX hotkeys, these key combinations can't be changed, so if you have some other emulator functions assigned to Ctrl, Insert or Delete, you'll have to change emulator settings.

          -


          -
          -

          -

          -

          -

          Under the Splicer you can see a small Lua section.

          -

          There is one inactive button and one checkbox here, their purpose will be described later. While you're not familiar with Lua scripting, you won't need this section.

          -

          The Lua scripting language allows to automate some part of TASers' work and to create your own plug-ins for Taseditor.

          -


          -
          -

          -

          -

          -

          Then goes the Bookmarks/Branches section. We should speak of Bookmarks at a greater length here.

          -

          Bookmarks are the evolution of emulator savestates. Before Taseditor the savestates were the main way to navigate the movie, with their help TASers return back to the place of a mistake and fix it. In Taseditor there are better navigation methods, but this one was left too.

          -

          You have 10 slots for Bookmarks in your disposal. These are numbered with digits from 0 to 9. You can set any of 10 Bookmarks to any movie frame, pointing to that frame with the Playback cursor beforehand.

          -

          Example 1. Set the light-blue cursor to the frame you want a Bookmark at, and make an emulator savestate (Shift + F1-F10 by default). For example, press Shift + F1 to set the first Bookmark. It will appear in the Bookmarks List, flashing one time with the red light.

          -

          Example 2. Set the light-blue cursor to the needed frame and right-click on any line in the Bookmarks List. For example, right-click on the line 2 to create the Bookmark in slot 2.

          -


          -

          You can undo the Bookmark set operations with Ctrl + Z.

          -

          The Bookmarks List displays the frame number where each Bookmark is sat, and the real time of setting the Bookmark. If you hover the mouse cursor over a Bookmark's time (the right column in the List), you'll see the screenshot from the game.

          -


          -

          When setting a Bookmark, Taseditor saves to the chosen slot the data about the Playback cursor position and entire movie contents. Now at any time you can either make a "spatial jump to the Bookmark" (simply returning the Playback cursor to the bookmarked place), or make a "temporal jump to the Bookmark", returning the whole movie to the state saved in the Bookmark slot.

          -

          To jump to a Bookmark in space, left-click on the left half of the needed Bookmark (the pale-colored half of the Bookmarks List where the frame number is displayed). Or use the keyboard – press the corresponding number key (numeric keys 0-9 are under the F1-F10 keys). You can notice the jump by seeing the light-blue cursor movement in the Piano Roll and by green flash in the Bookmarks List.

          -

          To jump to a Bookmark in time, left-click on the right half of the needed Bookmark (the brighter-colored half of the Bookmark List where the time is displayed). Or load the corresponding emulator savestate (keys F1-F10 by default). If any Input was changed during this jump in time (since it returns to its state at the time of creating the Bookmark), the Bookmark flashes with blue color, otherwise it flashes green, like in a simple Playback cursor jump. As usual, when an Input changes, the Greenzone truncates automatically. And of course you can undo the change using Ctrl + Z to revert the movie to its state before the time jump to the Bookmark.

          -


          -

          So, part of the Bookmarks may be used to speed up your movie navigation. For example, set a Bookmark at the beginning of current game level to be able to return the Playback cursor to that frame and replay the level events anytime. You could use a Marker for the same purpose, but the advantage of the Bookmarks is that you can instantly jump to a Bookmark from any remote segment of the movie, no matter how many Markers are set in between, while to reach the desired Marker you would have to jump on the neighbor Markers.

          -

          Another part of the Bookmarks can be used to store alternative approaches to playing the same game segment. When TASing complex games we can't always immediately evaluate the optimality of a playing strategy. Sometimes TASer needs to record several different versions of playing the same segment and then carefully compare the resulting movies, choosing the most appropriate one to be left in the final TAS.

          -

          In traditional TASing every such movie is kept in separate file, so to switch between the alternative movies (or rather between alternative branches of your main movie) you need to load corresponding savestates created when recording these playthroughs.

          -

          -

          In Taseditor all saved branches of the movie are held together, forming the hierarchy called the Branches Tree. To switch between the alternative branches you need to load the corresponding Bookmark, thus returning the working movie to one of the prepared versions. Basically, it's the same as before. But now we can visualize all alternative playthroughs in a graph scheme to facilitate TASer's comprehension of the multitude of options.

          -

          When you test a couple of approaches to playing the 2nd level of the game, the 1st level playthrough remains the same in both branches, so the discrepancy of the Input starts not from the beginning, but from the 2nd level. So, if you left the Bookmark 1 before the beginning of the 2nd level, you'll see the fork in the graph starting from the card 1.

          -

          As an experiment, create a new project and make a very short movie. Then set the Playback cursor to the end of existing Input and save a Bookmark into the first slot (Shift + F1). Advance a few frames after that Bookmark and draw some buttonpresses, then play this new Input and save to Bookmark 2 (Shift + F2). Now return the movie to the first Bookmark state (press F1) and add some buttonpresses after the bookmarked frame again, but make sure they are different from the last time. Play this new Input to the end and save the 3rd Bookmark (Shift + F3) or any other.

          -

          Now click on the header of the Bookmarks section ("Bookmarks/Branches" label). The Bookmarks List view will change to the Branches Tree view. If the third Bookmark movie differs from the second Bookmark movie, and the difference starts after the first Bookmark frame, you'll see the picture similar to the above. The cloudlet symbolizes the beginning of the movie (the root of the hierarchy). Bookmarks are presented with cards of corresponding numbers. The blue-colored number stands for the current Bookmark containing the branch that corresponds to working movie (currently displayed in the Piano Roll). If the working movie was changed after saving/loading this Bookmark, you'll see the fireball descending from the current Bookmark.

          -

          Red lines connect those Bookmarks that are compatible with the chronology of current working movie. For example, if you set one Bookmark at the end of every level, all such Bookmarks will be sitting on one red line, because the movie of every next Bookmark is actually composed from the movie of previous Bookmark plus an additional level playthrough.

          -

          The Branches Tree also displays current Playback cursor position. Try dragging the cursor in the Piano Roll up and down, or just play the whole movie back (press Shift + Home and unpause the emulator). You will see how the light-blue arrow pointer rides on red lines that connect all Bookmarks of the current timeline. E.g. if the current branch is the Bookmark 2, the pointer will ride that route: "cloudlet -> Bookmark 1 -> Bookmark 2". And the other Bookmarks will be left aside, because they represent an alternative timeline, conflicting with the currently played movie.

          -

          The Branches Tree is automatically rebuilt each time you create a new Bookmark or change an existing Bookmark's contents. Depending on how complex your project is, the graph may appear differently.

          -


          -
          - - - - - - - - - - +


          +

          When TASing in Taseditor you're going to most often use Ctrl + Delete (Delete Frames) and Ctrl + Insert (Clone Frames) to quickly move edited segments up/down in the frame list, thus performing certain in-game actions sooner or later.

          +

          Unlike FCEUX hotkeys, these key combinations can't be changed, so if you have some other emulator functions assigned to Ctrl, Insert or Delete, you'll have to change emulator settings.

          +


          +
          +


          +

          +

          Under the Splicer you can see a small Lua section.

          +

          There is one inactive button and one checkbox here, their purpose will be described later. While you're not familiar with Lua scripting, you won't need this section.

          +

          The Lua scripting language allows to automate some part of TASers' work and to create your own plug-ins for Taseditor.

          +


          +
          +


          +

          +

          Then goes the Bookmarks/Branches section. We should speak of Bookmarks at a greater length here.

          +

          Bookmarks are the evolution of emulator savestates. Before Taseditor the savestates were the main way to navigate the movie, with their help TASers return back to the place of a mistake and fix it. In Taseditor there are better navigation methods, but this one was left too.

          +

          You have 10 slots for Bookmarks in your disposal. These are numbered with digits from 0 to 9. You can set any of 10 Bookmarks to any movie frame, pointing to that frame with the Playback cursor beforehand.

          +

          Example 1. Set the light-blue cursor to the frame you want a Bookmark at, and make an emulator savestate (Shift + F1-F10 by default). For example, press Shift + F1 to set the first Bookmark. It will appear in the Bookmarks List, flashing one time with the red light.

          +

          Example 2. Set the light-blue cursor to the needed frame and right-click on any line in the Bookmarks List. For example, right-click on the line 2 to create the Bookmark in slot 2.

          +


          +

          You can undo the Bookmark set operations with Ctrl + Z.

          +

          The Bookmarks List displays the frame number where each Bookmark is sat, and the real time of setting the Bookmark. If you hover the mouse cursor over a Bookmark's time (the right column in the List), you'll see the screenshot from the game.

          +


          +

          When setting a Bookmark, Taseditor saves to the chosen slot the data about the Playback cursor position and entire movie contents. Now at any time you can either make a "spatial jump to the Bookmark" (simply returning the Playback cursor to the bookmarked place), or make a "temporal jump to the Bookmark", returning the whole movie to the state saved in the Bookmark slot.

          +

          To jump to a Bookmark in space, left-click on the left half of the needed Bookmark (the pale-colored half of the Bookmarks List where the frame number is displayed). Or use the keyboard – press the corresponding number key (numeric keys 0-9 are under the F1-F10 keys). You can notice the jump by seeing the light-blue cursor movement in the Piano Roll and by green flash in the Bookmarks List.

          +

          To jump to a Bookmark in time, left-click on the right half of the needed Bookmark (the brighter-colored half of the Bookmark List where the time is displayed). Or load the corresponding emulator savestate (keys F1-F10 by default). If any Input was changed during this jump in time (since it returns to its state at the time of creating the Bookmark), the Bookmark flashes with blue color, otherwise it flashes green, like in a simple Playback cursor jump. As usual, when an Input changes, the Greenzone truncates automatically. And of course you can undo the change using Ctrl + Z to revert the movie to its state before the time jump to the Bookmark.

          +


          +

          So, part of the Bookmarks may be used to speed up your movie navigation. For example, set a Bookmark at the beginning of current game level to be able to return the Playback cursor to that frame and replay the level events anytime. You could use a Marker for the same purpose, but the advantage of the Bookmarks is that you can instantly jump to a Bookmark from any remote segment of the movie, no matter how many Markers are set in between, while to reach the desired Marker you would have to jump on the neighbor Markers.

          +

          Another part of the Bookmarks can be used to store alternative approaches to playing the same game segment. When TASing complex games we can't always immediately evaluate the optimality of a playing strategy. Sometimes TASer needs to record several different versions of playing the same segment and then carefully compare the resulting movies, choosing the most appropriate one to be left in the final TAS.

          +

          In traditional TASing every such movie is kept in separate file, so to switch between the alternative movies (or rather between alternative branches of your main movie) you need to load corresponding savestates created when recording these playthroughs.

          +

          +

          In Taseditor all saved branches of the movie are held together, forming the hierarchy called the Branches Tree. To switch between the alternative branches you need to load the corresponding Bookmark, thus returning the working movie to one of the prepared versions. Basically, it's the same as before. But now we can visualize all alternative playthroughs in a graph scheme to facilitate TASer's comprehension of the multitude of options.

          +

          When you test a couple of approaches to playing the 2nd level of the game, the 1st level playthrough remains the same in both branches, so the discrepancy of the Input starts not from the beginning, but from the 2nd level. So, if you left the Bookmark 1 before the beginning of the 2nd level, you'll see the fork in the graph starting from the card 1.

          +

          As an experiment, create a new project and make a very short movie. Then set the Playback cursor to the end of existing Input and save a Bookmark into the first slot (Shift + F1). Advance a few frames after that Bookmark and draw some buttonpresses, then play this new Input and save to Bookmark 2 (Shift + F2). Now return the movie to the first Bookmark state (press F1) and add some buttonpresses after the bookmarked frame again, but make sure they are different from the last time. Play this new Input to the end and save the 3rd Bookmark (Shift + F3) or any other.

          +

          Now click on the header of the Bookmarks section ("Bookmarks/Branches" label). The Bookmarks List view will change to the Branches Tree view. If the third Bookmark movie differs from the second Bookmark movie, and the difference starts after the first Bookmark frame, you'll see the picture similar to the above. The cloudlet symbolizes the beginning of the movie (the root of the hierarchy). Bookmarks are presented with cards of corresponding numbers. The blue-colored number stands for the current Bookmark containing the branch that corresponds to working movie (currently displayed in the Piano Roll). If the working movie was changed after saving/loading this Bookmark, you'll see the fireball descending from the current Bookmark.

          +

          Red lines connect those Bookmarks that are compatible with the chronology of current working movie. For example, if you set one Bookmark at the end of every level, all such Bookmarks will be sitting on one red line, because the movie of every next Bookmark is actually composed from the movie of previous Bookmark plus an additional level playthrough.

          +

          The Branches Tree also displays current Playback cursor position. Try dragging the cursor in the Piano Roll up and down, or just play the whole movie back (press Shift + Home and unpause the emulator). You will see how the light-blue arrow pointer rides on red lines that connect all Bookmarks of the current timeline. E.g. if the current branch is the Bookmark 2, the pointer will ride that route: "cloudlet -> Bookmark 1 -> Bookmark 2". And the other Bookmarks will be left aside, because they represent an alternative timeline, conflicting with the currently played movie.

          +

          The Branches Tree is automatically rebuilt each time you create a new Bookmark or change an existing Bookmark's contents. Depending on how complex your project is, the graph may appear differently.

          +


          +
          +

          -

          -

          -

          -

          -

          -
          + + + + + + + + + +
          +

          +
          +

          +
          +

          +
          +

          +
          +

          +
          +

          +
          -


          -

          You can hover the mouse cursor over any Bookmark number to see some info about it.

          -

          Also you can make a single left-click on any Bookmark card to send the Playback cursor to the bookmarked frame (spatial jump). By clicking the cloudlet you send the Playback cursor to the beginning of the movie (equal to pressing Shift + Home), and by clicking the fireball you send the Playback cursor to the end of the movie (equal to Shift + End).

          -

          Besides, you can double-click a Bookmark by the left mouse button to jump to the Bookmark in time. The working movie reverts to the Bookmark's state, the Bookmark becomes current branch and the Playback cursor moves to the Bookmark frame.

          -

          Finally, you can right-click any card to save the current movie state and the Playback cursor position to the chosen Bookmark.

          -

          As you see, the Branches Tree view supports the same functionality as the Bookmarks List view does. Thus it's recommended for advanced users to stick to the Branch Tree view, because it provides more info for a TASer. When you want to switch back to the Bookmarks List view, click the section header again (the "Branches" label).

          -

          Now try using all 10 available slots. Each time slightly change the current movie Input and watch the changes on the FCEUX screen before saving them to a Bookmark. The position of each card on the Tree is defined by the Input preceding the bookmarked frame. It's implied that TASer always watches the edited Input segment in the emulator, and only then saves the tested work into a Bookmark.

          -

          In hands of an experienced TASer Bookmarks become very powerful tool, allowing to greatly simplify the TASing process and implement ideas that look impossible. Usually, an idea is labeled "impossible" only due to its monstrous unbounded complexity. But lower the complexity a hundred times (with the help of tools and a smart process organization), and the achievement moves from the "impossible" category to just "hard" one.

          -


          -
          -

          -

          -

          -

          The History section is located below the Bookmarks.

          -

          Taseditor keeps strict accounting of all operations in the current project. Every user's action that changes an Input, Markers or Bookmarks is recorded to the log displayed in this section.

          -

          The current item of the History Log is highlighted blue. Other items have white background if they aren't related to the current item, or purple background if they represent the changes made in the same place as the current item. For example, if current History Log item was created by changing the Input of frame 27, all other items affecting that frame will be highlighted purple.

          -

          To undo logged operations you can either use the Ctrl + Z and Ctrl + Y keys, or simply click any line in the History Log with the left mouse button, thus returning the movie to the time when the clicked item was created.

          -

          You may notice the purple cursor line appearing in the Piano Roll for a short moment. It's supposed to stress your attention on the place of the undone changes.

          -

          The maximum number of undo levels can be set in the Config menu, that value defines the maximum size of the History Log and therefore the amount of used memory.

          -

          The full list of all possible records in the History Log can be found in the Reference.

          -


          -
          -

          -

          -

          -

          At the very bottom of the Toolbox there are 4 buttons controlling the Selection cursor.

          -

          The meaning of the "<<" and ">>" buttons can be easily guessed by analogy with the upper "<<" and ">>" buttons in the Playback section. The upper part of TAS Editor window contains the Playback cursor-related elements, and the lower window part contains Selection cursor-related elements.

          -

          The "<<" button (jump back) moves the Selection cursor to the frame where the nearest upper Marker is located. In the above picture it will jump from frame 27 to frame 22 where the Marker 2 is set. Using this button you can quickly return the selection to the beginning of the edited segment or to any marked segment. This button has its keyboard analog: Ctrl + Page Up. You can hold this button to let the dark-blue cursor rapidly jump on Markers up in the Piano Roll.

          -

          The ">>" button (jump forward) moves the Selection cursor to the nearest marked frame below it. In the above picture it will jump from frame 27 to a frame outside the visible area (where the next Marker is set), and Piano Roll will automatically scroll after the Selection cursor. Using this button you can quickly navigate down through the movie. This button has its keyboard analog: Ctrl + Page Down. You can hold this button as well.

          -

          Since the Selection cursor isn't tied to the game emulation, its jumps on Markers always happen instantly, regardless of the Greenzone presence on the target frame. So it's useful to read the Marker Notes one by one this way, watching them in the lower edit field and pressing Ctrl + Page Down to make an instant jump to the next Note. Besides Page Up / Page Down keys you can roll the mouse wheel while holding the Ctrl key.

          -


          -

          The buttons "Similar" and "More" are used for searching similar Notes. This is another experimental feature of Taseditor, and it will be described later.

          -


          -
          -


          -

          Now you are familiar with fundamental principles of the program usage.

          -

          In the next chapter: systematic approach to TASing.

          -


          -
          - - - +


          +

          You can hover the mouse cursor over any Bookmark number to see some info about it.

          +

          Also you can make a single left-click on any Bookmark card to send the Playback cursor to the bookmarked frame (spatial jump). By clicking the cloudlet you send the Playback cursor to the beginning of the movie (equal to pressing Shift + Home), and by clicking the fireball you send the Playback cursor to the end of the movie (equal to Shift + End).

          +

          Besides, you can double-click a Bookmark by the left mouse button to jump to the Bookmark in time. The working movie reverts to the Bookmark's state, the Bookmark becomes current branch and the Playback cursor moves to the Bookmark frame.

          +

          Finally, you can right-click any card to save the current movie state and the Playback cursor position to the chosen Bookmark.

          +

          As you see, the Branches Tree view supports the same functionality as the Bookmarks List view does. Thus it's recommended for advanced users to stick to the Branch Tree view, because it provides more info for a TASer. When you want to switch back to the Bookmarks List view, click the section header again (the "Branches" label).

          +

          Now try using all 10 available slots. Each time slightly change the current movie Input and watch the changes on the FCEUX screen before saving them to a Bookmark. The position of each card on the Tree is defined by the Input preceding the bookmarked frame. It's implied that TASer always watches the edited Input segment in the emulator, and only then saves the tested work into a Bookmark.

          +

          In hands of an experienced TASer Bookmarks become very powerful tool, allowing to greatly simplify the TASing process and implement ideas that look impossible. Usually, an idea is labeled "impossible" only due to its monstrous unbounded complexity. But lower the complexity a hundred times (with the help of tools and a smart process organization), and the achievement moves from the "impossible" category to just "hard" one.

          +


          +
          +


          +

          +

          The History section is located below the Bookmarks.

          +

          Taseditor keeps strict accounting of all operations in the current project. Every user's action that changes an Input, Markers or Bookmarks is recorded to the log displayed in this section.

          +

          The current item of the History Log is highlighted blue. Other items have white background if they aren't related to the current item, or purple background if they represent the changes made in the same place as the current item. For example, if current History Log item was created by changing the Input of frame 27, all other items affecting that frame will be highlighted purple.

          +

          To undo logged operations you can either use the Ctrl + Z and Ctrl + Y keys, or simply click any line in the History Log with the left mouse button, thus returning the movie to the time when the clicked item was created. 

          +

          You may notice the purple cursor line appearing in the Piano Roll for a short moment. It's supposed to stress your attention on the place of the undone changes.

          +

          The maximum number of undo levels can be set in the Config menu, that value defines the maximum size of the History Log and therefore the amount of used memory.

          +

          The full list of all possible records in the History Log can be found in the Reference.

          +


          +
          +


          +

          +

          At the very bottom of the Toolbox there are 4 buttons controlling the Selection cursor.

          +

          The meaning of the "<<" and ">>" buttons can be easily guessed by analogy with the upper "<<" and ">>" buttons in the Playback section. The upper part of TAS Editor window contains the Playback cursor-related elements, and the lower window part contains Selection cursor-related elements.

          +

          The "<<" button (jump back) moves the Selection cursor to the frame where the nearest upper Marker is located. In the above picture it will jump from frame 27 to frame 22 where the Marker 2 is set. Using this button you can quickly return the selection to the beginning of the edited segment or to any marked segment. This button has its keyboard analog: Ctrl + Page Up. You can hold this button to let the dark-blue cursor rapidly jump on Markers up in the Piano Roll.

          +

          The ">>" button (jump forward) moves the Selection cursor to the nearest marked frame below it. In the above picture it will jump from frame 27 to a frame outside the visible area (where the next Marker is set), and Piano Roll will automatically scroll after the Selection cursor. Using this button you can quickly navigate down through the movie. This button has its keyboard analog: Ctrl + Page Down. You can hold this button as well.

          +

          Since the Selection cursor isn't tied to the game emulation, its jumps on Markers always happen instantly, regardless of the Greenzone presence on the target frame. So it's useful to read the Marker Notes one by one this way, watching them in the lower edit field and pressing Ctrl + Page Down to make an instant jump to the next Note. Besides Page Up / Page Down keys you can roll the mouse wheel while holding the Ctrl key.

          +


          +

          The buttons "Similar" and "More" are used for searching similar Notes. This is another experimental feature of Taseditor, and it will be described later.

          +


          +
          +


          +

          Now you are familiar with fundamental principles of the program usage.

          +

          In the next chapter: systematic approach to TASing.

          +


          +
          +

          PRACTICE: Beat the World 1-1 in Super Mario Bros (or any other game) using only the mouse, without Recording.

          -

          No need to do a speedrun, just make yourself familiar with the routine of Input drawing / erasing and watching the results using the mouse wheel / middle mouse button.

          -

          Estimated time: 20-30 minutes.

          -
          + + +
          +

          PRACTICE: Beat the World 1-1 in Super Mario Bros (or any other game) using only the mouse, without Recording.

          +

          No need to do a speedrun, just make yourself familiar with the routine of Input drawing / erasing and watching the results using the mouse wheel / middle mouse button.

          +

          Estimated time: 20-30 minutes.

          +
          -


          -


          -


          -


          -


          +


          +


          +


          +


          +


          -

          Created with the Personal Edition of HelpNDoc: Easily create Help documents

          -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/TraditionalTASing.html b/web/help/taseditor/TraditionalTASing.html index eb646059..c19077ba 100644 --- a/web/help/taseditor/TraditionalTASing.html +++ b/web/help/taseditor/TraditionalTASing.html @@ -1,147 +1,337 @@ - - + + + + + - 4.1. Traditional TASing - - - - - - - - - - + + + + + + + + 4.1. Traditional TASing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + -
      -
      -

      4.1. Traditional TASing

      - - -
      -
      - Parent - - Previous - - Next - -
      -
      -
      -
      - + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      4.1. Traditional TASing

      + +
      +

      -

      Traditional TASing

      -


      -


      -

      -

      This method is similar in form to normal videogames playing, however it is completely different in content and requires different way of thinking.

      -

      Editing Input is done here by recording a new Input over existing Input.

      -

      To switch between movie watching and editing you have to turn the Recording mode off and on (default hotkey is Q). It's recommended to enable the "Follow cursor" checkbox, in order to observe the recorded Input in the Piano Roll.

      -


      -

      General activity:

      -


      -
        -
      1. Put the Playback cursor at the beginning of the edited segment, create a Bookmark, define the goal.
      2. -
      3. Suppose there's a mistake in the segment, weigh known factors of optimality and figure out the way to fix the mistake.
      4. -
      5. Navigate to the place of fixing the mistake (e.g. load a Bookmark and, if necessary, quickly repeat the existing Input up to the needed frame).
      6. -
      7. Play the game in Read+Write mode up to the moment when the target event occurs. The newly recorded Input should be different from old Input in this segment. While recording, create Bookmarks in free slots from time to time to speed up navigation.
      8. -
      9. If you make a mistake while typing the Input, return to step 3. If you fail to reach the target event using the chosen approach, you can retreat and go to step 8.
      10. -
      11. [optional step] Save the finished approach to a temporary Bookmark, e.g. to slot 8 or 7.
      12. -
      13. If this isn't the first approach to the segment, compare the new result to the best old result, using the optimality criterion. If the new approach is better (or it's the first approach), save the result to the Bookmark 9. The slot 9 will be used for keeping the best result of polishing the segment.
      14. -
      15. If you still want to try different approaches, return to step 2, until you run out of ideas.
      16. -
      17. [optional step] If you need more ideas, you can get some information from the past by replaying the old segments of the movie (e.g. load the Bookmark 0 left at the beginning of current level). Also you can get some food for the mind from the future, by playing with the game events happening after the current segment.
      18. -
      19. When there's no more ideas, restore the best approach from the Bookmark 9 into the current movie and proceed to the next segment.
      20. +

        Traditional TASing

        +


        +


        +

        +

        This method is similar in form to normal videogames playing, however it is completely different in content and requires different way of thinking.

        +

        Editing Input is done here by recording a new Input over existing Input.

        +

        To switch between movie watching and editing you have to turn the Recording mode off and on (default hotkey is Q). It's recommended to enable the "Follow cursor" checkbox, in order to observe the recorded Input in the Piano Roll.

        +


        +

        General activity:

        +


        +
          +
        1. Put the Playback cursor at the beginning of the edited segment, create a Bookmark, define the goal.
        2. +
        3. Suppose there's a mistake in the segment, weigh known factors of optimality and figure out the way to fix the mistake.
        4. +
        5. Navigate to the place of fixing the mistake (e.g. load a Bookmark and, if necessary, quickly repeat the existing Input up to the needed frame).
        6. +
        7. Play the game in Read+Write mode up to the moment when the target event occurs. The newly recorded Input should be different from old Input in this segment. While recording, create Bookmarks in free slots from time to time to speed up navigation.
        8. +
        9. If you make a mistake while typing the Input, return to step 3. If you fail to reach the target event using the chosen approach, you can retreat and go to step 8.
        10. +
        11. [optional step] Save the finished approach to a temporary Bookmark, e.g. to slot 8 or 7.
        12. +
        13. If this isn't the first approach to the segment, compare the new result to the best old result, using the optimality criterion. If the new approach is better (or it's the first approach), save the result to the Bookmark 9. The slot 9 will be used for keeping the best result of polishing the segment.
        14. +
        15. If you still want to try different approaches, return to step 2, until you run out of ideas.
        16. +
        17. [optional step] If you need more ideas, you can get some information from the past by replaying the old segments of the movie (e.g. load the Bookmark 0 left at the beginning of current level). Also you can get some food for the mind from the future, by playing with the game events happening after the current segment.
        18. +
        19. When there's no more ideas, restore the best approach from the Bookmark 9 into the current movie and proceed to the next segment.
        -


        -
        -


        -

        When you're making a test playthrough of the game (i.e. playing with savestates, but without polishing), you only do steps 3 – 5. And you are satisfied with any successful accomplishment of a segment, so after reaching the target for the first time you proceed to the next segment right away. In this kind of playing you only use savestates to speed up navigation in case you make a fatal mistake (e.g. didn't press the A button in time and fell into the pit), only because you don't want to rewrite existing Input from the very beginning of the game.

        -

        But when you're seriously TASing the game, you need to try many different approaches in order to find the best one. So you have to repeat steps 2 – 8 many times, until you think the segment is played perfectly. The steps 6 – 9 are what distinguishes real TASing from casual playing with savestates.

        -

        The process of Input Recording (step 4) means that you're editing the Input right while watching the results. That is, when watching the paused game state at the frame 200 you prepare the Input for the frame 201 (lay fingers on necessary buttons) and then pass the Input to the game using Frame Advance, and immediately see the outcome – the game state at the frame 201 (granted that you look at the Memory Watch, because the game screen rendering is one frame behind). Usually this outcome is only an intermediate result, which means you can use it to estimate your progress (step 5) but should not use it to compare current and previous approaches of playing the segment (step 7). So you shouldn't apply the optimality criterion after every frame. Even if at the beginning of the segment you outrun the previous approach, you may fall behind somewhere in the middle. Only when you reach the end of the segment (step 6) you get an objective base for comparing.

        -

        Steps 3 and 4 take the most of time in this cycle. Often before reaching the target event you have to repeat steps 3, 5 and 5 several times in a row, recording and discarding decisions that are obviously wrong even without comparing them to old approaches. For example, if in the middle of acceleration Mario gets killed by an enemy, there's no point in entering the remaining buttons needed for acceleration. You have to return back and rewrite the Input in such a way that the enemy misses. In a tough situation it's even better to break current segment into two subsegments (before and after the interaction with the enemy), in order to optimize them separately. If you don't do so, you will probably become tired after finishing the first approach, and you'll decide to leave the segment as it is. See, you've got to manage your effort optimally as well!

        -

        -

        -

        Since the Input editing in this method is done using the Playback cursor (and not the mouse cursor), for an effective work you must learn to quickly deliver the light-blue cursor to any frame necessary. Upon gaining an experience, TASers accustom themselves to "juggle" with Bookmarks using the motor memory. They mechanically create intermediate and auxiliary Bookmarks while recording the Input, and find the necessary Bookmark slot without looking.

        -

        This virtuosity comes with time, usually after having finished a couple of TASes. You cultivate certain habits, one finger adheres to Frame Advance key, Bookmark slots become logically distributed according to their duties, so that fingers press right keys at right moments on their own. For example, that's how some TASers distribute 10 slots:

        -


        -

        -


        -
          -
        • F10 points to the beginning of current level of the game, so you can see recent segments without rewatching the whole movie. Used for navigation.
        • -
        • F9 is responsible for keeping the best result of current segment. Used for storing.
        • -
        • F2-F6 serve as Bookmarks left after every hard-to-reproduce action of the current approach to the segment. These Bookmarks are needed for a quick navigation along the current segment. One of them points to the beginning of the segment, and other are used when necessary (may be left unused, if the segment is short and simple). These Bookmarks are created mechanically while successfully progressing with Input Recording. Used for navigation.
        • -
        • F1 stores a backup copy of the movie at the last successful frame. Current movie state is saved to this slot with paranoid frequency, so you could always return to this stable state from any situation (e.g. after loading some other Bookmarks, or after recording an experiment). This is how the traditional method implements simple undo feature. Sometimes in addition to the F1 people use F2 to provide two levels of undo, but this complicates the logic of backups (as you'd have to alternate the slots), and usually one slot is sufficient. Used for storing.
        • -
        • F7-F8 may store results of alternative strategies that aren't better than the contents of the F9, yet they are of some interest. Also, one of these slots (or one of F2-F6) is used during step 6 to temporarily save the result of the newly finished approach, in order to compare it to the old best result more precisely (by quickly switching between F8 and F9). Used for storing.
        • -
        • When creating an improvement for someone else's TAS, slots F5-F7 may be allotted for various points of the old movie. For example, F5 is responsible for the beginning of current level in old movie, F6 – for the beginning of current segment in old movie, F7 – for the end of the current segment in old movie. Used for storing and navigating the old movie contents.
        • +


          +
          +


          +

          When you're making a test playthrough of the game (i.e. playing with savestates, but without polishing), you only do steps 3 – 5. And you are satisfied with any successful accomplishment of a segment, so after reaching the target for the first time you proceed to the next segment right away. In this kind of playing you only use savestates to speed up navigation in case you make a fatal mistake (e.g. didn't press the A button in time and fell into the pit), only because you don't want to rewrite existing Input from the very beginning of the game.

          +

          But when you're seriously TASing the game, you need to try many different approaches in order to find the best one. So you have to repeat steps 2 – 8 many times, until you think the segment is played perfectly. The steps 6 – 9 are what distinguishes real TASing from casual playing with savestates.

          +

          The process of Input Recording (step 4) means that you're editing the Input right while watching the results. That is, when watching the paused game state at the frame 200 you prepare the Input for the frame 201 (lay fingers on necessary buttons) and then pass the Input to the game using Frame Advance, and immediately see the outcome – the game state at the frame 201 (granted that you look at the Memory Watch, because the game screen rendering is one frame behind). Usually this outcome is only an intermediate result, which means you can use it to estimate your progress (step 5) but should not use it to compare current and previous approaches of playing the segment (step 7). So you shouldn't apply the optimality criterion after every frame. Even if at the beginning of the segment you outrun the previous approach, you may fall behind somewhere in the middle. Only when you reach the end of the segment (step 6) you get an objective base for comparing.

          +

          Steps 3 and 4 take the most of time in this cycle. Often before reaching the target event you have to repeat steps 3, 5 and 5 several times in a row, recording and discarding decisions that are obviously wrong even without comparing them to old approaches. For example, if in the middle of acceleration Mario gets killed by an enemy, there's no point in entering the remaining buttons needed for acceleration. You have to return back and rewrite the Input in such a way that the enemy misses. In a tough situation it's even better to break current segment into two subsegments (before and after the interaction with the enemy), in order to optimize them separately. If you don't do so, you will probably become tired after finishing the first approach, and you'll decide to leave the segment as it is. See, you've got to manage your effort optimally as well!

          +


          +

          Since the Input editing in this method is done using the Playback cursor (and not the mouse cursor), for an effective work you must learn to quickly deliver the light-blue cursor to any frame necessary. Upon gaining an experience, TASers accustom themselves to "juggle" with Bookmarks using the motor memory. They mechanically create intermediate and auxiliary Bookmarks while recording the Input, and find the necessary Bookmark slot without looking.

          +

          This virtuosity comes with time, usually after having finished a couple of TASes. You cultivate certain habits, one finger adheres to Frame Advance key, Bookmark slots become logically distributed according to their duties, so that fingers press right keys at right moments on their own. For example, that's how some TASers distribute 10 slots:

          +


          +

          +


          +
            +
          • F10 points to the beginning of current level of the game, so you can see recent segments without rewatching the whole movie. Used for navigation.
          • +
          • F9 is responsible for keeping the best result of current segment. Used for storing.
          • +
          • F2-F6 serve as Bookmarks left after every hard-to-reproduce action of the current approach to the segment. These Bookmarks are needed for a quick navigation along the current segment. One of them points to the beginning of the segment, and other are used when necessary (may be left unused, if the segment is short and simple). These Bookmarks are created mechanically while successfully progressing with Input Recording. Used for navigation.
          • +
          • F1 stores a backup copy of the movie at the last successful frame. Current movie state is saved to this slot with paranoid frequency, so you could always return to this stable state from any situation (e.g. after loading some other Bookmarks, or after recording an experiment). This is how the traditional method implements simple undo feature. Sometimes in addition to the F1 people use F2 to provide two levels of undo, but this complicates the logic of backups (as you'd have to alternate the slots), and usually one slot is sufficient. Used for storing.
          • +
          • F7-F8 may store results of alternative strategies that aren't better than the contents of the F9, yet they are of some interest. Also, one of these slots (or one of F2-F6) is used during step 6 to temporarily save the result of the newly finished approach, in order to compare it to the old best result more precisely (by quickly switching between F8 and F9). Used for storing.
          • +
          • When creating an improvement for someone else's TAS, slots F5-F7 may be allotted for various points of the old movie. For example, F5 is responsible for the beginning of current level in old movie, F6 – for the beginning of current segment in old movie, F7 – for the end of the current segment in old movie. Used for storing and navigating the old movie contents.
          -


          -

          This skill is very similar to the skill of playing a musical instrument. The quicker you work it out, the better, because until you master it you will think the traditional TASing is too tiresome. That's why many people consider the bar to be too high. But once you master the technique of rapid savestates usage, other intricacies of TASing will come easier.

          -

          However, now there is Taseditor. It revokes the need to train fingers, allowing to quickly navigate the movie without using Bookmarks. Also, you don't need to accustom to constant backups into F1, since there is the History Log. So technically you can forget about the traditional method and right away start editing the movie and testing approaches using the nonlinear method of TASing.

          -

          Anyway, Taseditor slightly expands possibilities of the traditional method:

          -
            -
          • New ways to navigate with the Playback cursor, allowing to get to the needed place faster and create savestates less often.
          • -
          • When loading a Bookmark, the movie doesn't truncate after the bookmarked frame. This allows, for example, to record the segment of frames 900-1000 and then rerecord the segment 700-900 without losing the data from 900-1000.
          • -
          • All possibilities of an external Input editor (copy/paste, etc).
          • -
          • Visualization of Bookmarks, Input, lag and so on.
          • -
          • Additional tools: multitracking, superimposing, auto-adjustment of Input, etc.
          • +


            +

            This skill is very similar to the skill of playing a musical instrument. The quicker you work it out, the better, because until you master it you will think the traditional TASing is too tiresome. That's why many people consider the bar to be too high. But once you master the technique of rapid savestates usage, other intricacies of TASing will come easier.

            +

            However, now there is Taseditor. It revokes the need to train fingers, allowing to quickly navigate the movie without using Bookmarks. Also, you don't need to accustom to constant backups into F1, since there is the History Log. So technically you can forget about the traditional method and right away start editing the movie and testing approaches using the nonlinear method of TASing.

            +

            Anyway, Taseditor slightly expands possibilities of the traditional method:

            +
              +
            • New ways to navigate with the Playback cursor, allowing to get to the needed place faster and create savestates less often.
            • +
            • When loading a Bookmark, the movie doesn't truncate after the bookmarked frame. This allows, for example, to record the segment of frames 900-1000 and then rerecord the segment 700-900 without losing the data from 900-1000.
            • +
            • All possibilities of an external Input editor (copy/paste, etc).
            • +
            • Visualization of Bookmarks, Input, lag and so on.
            • +
            • Additional tools: multitracking, superimposing, auto-adjustment of Input, etc.
            -


            -
            -


            -

            Pros of the method:

            -

            + The process is intuitive for any gamer.

            -

            + Constant feedback allows to adapt to the game while editing the Input, adjust your decisions and discard incorrect approaches prematurely.

            -

            + The boundaries of current segment are always marked with Bookmarks (for navigation), thus training TASer to be orderly (which will pay off).

            -


            -

            Cons of the method:

            -

            The insistent game feedback provokes TASer to discard some illogical but potentially advantageous approaches.

            -

            Slow navigation may distract and increase fatigability.

            -

            Since the number of Bookmarks is limited, the markings of previous segments are lost when creating a new segment, so you have to write down some things in a text file.

            -


            -

            When the method is recommended to use: never. You can use the Recording to make the first test playthrough of a segment (or the whole game), i.e. when you don't need precision. But for polishing a segment this method is inferior. Yet it's reasonable to learn it, because many modern emulators have sufficient tools for applying the method, while Taseditor is only in FCEUX as yet.

            -


            -

            The next method is more effective, but it even less resembles a normal gaming.

            -


            -


            -


            -


            -


            +


            +
            +


            +

            Pros of the method:

            +

            + The process is intuitive for any gamer.

            +

            + Constant feedback allows to adapt to the game while editing the Input, adjust your decisions and discard incorrect approaches prematurely.

            +

            + The boundaries of current segment are always marked with Bookmarks (for navigation), thus training TASer to be orderly (which will pay off).

            +


            +

            Cons of the method:

            +

            The insistent game feedback provokes TASer to discard some illogical but potentially advantageous approaches.

            +

            Slow navigation may distract and increase fatigability.

            +

            Since the number of Bookmarks is limited, the markings of previous segments are lost when creating a new segment, so you have to write down some things in a text file.

            +


            +

            When the method is recommended to use: never. You can use the Recording to make the first test playthrough of a segment (or the whole game), i.e. when you don't need precision. But for polishing a segment this method is inferior. Yet it's reasonable to learn it, because many modern emulators have sufficient tools for applying the method, while Taseditor is only in FCEUX as yet.

            +


            +

            The next method is more effective, but it even less resembles a normal gaming.

            +


            +


            +


            +


            +


            -

            Created with the Personal Edition of HelpNDoc: Easily create CHM Help documents

            -
      - - + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + - -
      - - diff --git a/web/help/taseditor/_keywords.json b/web/help/taseditor/_keywords.json new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/web/help/taseditor/_keywords.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/web/help/taseditor/_toc.json b/web/help/taseditor/_toc.json new file mode 100644 index 00000000..a11177a1 --- /dev/null +++ b/web/help/taseditor/_toc.json @@ -0,0 +1 @@ +[{ "id": "Title", "parent" : "#", "text": "Title", "a_attr": {"href": "Title.html"} , "icon": "icon-20" },{ "id": "BeginnersGuide", "parent" : "#", "text": "Beginner's Guide", "a_attr": {"href": "BeginnersGuide.html"} },{ "id": "Introduction", "parent" : "BeginnersGuide", "text": "1. Introduction", "a_attr": {"href": "Introduction.html"} , "icon": "icon-1" },{ "id": "ProgramInterface", "parent" : "BeginnersGuide", "text": "2. Program Interface", "a_attr": {"href": "ProgramInterface.html"} },{ "id": "PianoRoll", "parent" : "ProgramInterface", "text": "2.1. Piano Roll", "a_attr": {"href": "PianoRoll.html"} , "icon": "icon-1" },{ "id": "Toolbox", "parent" : "ProgramInterface", "text": "2.2. Toolbox", "a_attr": {"href": "Toolbox.html"} , "icon": "icon-1" },{ "id": "TASingProcess", "parent" : "BeginnersGuide", "text": "3. TASing Process", "a_attr": {"href": "TASingProcess.html"} , "icon": "icon-1" },{ "id": "TASingMethodology", "parent" : "BeginnersGuide", "text": "4. TASing Methodology", "a_attr": {"href": "TASingMethodology.html"} },{ "id": "TraditionalTASing", "parent" : "TASingMethodology", "text": "4.1. Traditional TASing", "a_attr": {"href": "TraditionalTASing.html"} , "icon": "icon-1" },{ "id": "NonlinearTASing", "parent" : "TASingMethodology", "text": "4.2. Nonlinear TASing", "a_attr": {"href": "NonlinearTASing.html"} , "icon": "icon-1" },{ "id": "SemiautomaticTASing", "parent" : "TASingMethodology", "text": "4.3. Semiautomatic TASing", "a_attr": {"href": "SemiautomaticTASing.html"} , "icon": "icon-1" },{ "id": "ProgramCustomization", "parent" : "BeginnersGuide", "text": "5. Program customization", "a_attr": {"href": "ProgramCustomization.html"} , "icon": "icon-1" },{ "id": "AdvancedFeatures", "parent" : "BeginnersGuide", "text": "6. Advanced Features", "a_attr": {"href": "AdvancedFeatures.html"} , "icon": "icon-1" },{ "id": "Reference", "parent" : "#", "text": "Reference", "a_attr": {"href": "Reference.html"} },{ "id": "Glossary", "parent" : "Reference", "text": "Glossary", "a_attr": {"href": "Glossary.html"} , "icon": "icon-1" },{ "id": "Controls", "parent" : "Reference", "text": "Controls", "a_attr": {"href": "Controls.html"} , "icon": "icon-1" },{ "id": "Navigation", "parent" : "Reference", "text": "Navigation", "a_attr": {"href": "Navigation.html"} , "icon": "icon-1" },{ "id": "Operations", "parent" : "Reference", "text": "Operations", "a_attr": {"href": "Operations.html"} , "icon": "icon-1" },{ "id": "LuaAPI", "parent" : "Reference", "text": "Lua API", "a_attr": {"href": "LuaAPI.html"} , "icon": "icon-1" },{ "id": "FAQ", "parent" : "Reference", "text": "FAQ", "a_attr": {"href": "FAQ.html"} , "icon": "icon-1" },{ "id": "SpeedrunningSynopsis", "parent" : "Reference", "text": "Speedrunning synopsis", "a_attr": {"href": "SpeedrunningSynopsis.html"} , "icon": "icon-1" },{ "id": "TASEditorInside", "parent" : "#", "text": "TAS Editor Inside", "a_attr": {"href": "TASEditorInside.html"} },{ "id": "Ideas", "parent" : "TASEditorInside", "text": "Ideas", "a_attr": {"href": "Ideas.html"} , "icon": "icon-1" },{ "id": "Implementation", "parent" : "TASEditorInside", "text": "Implementation", "a_attr": {"href": "Implementation.html"} , "icon": "icon-1" },{ "id": "MistakeProofing", "parent" : "TASEditorInside", "text": "Mistake-proofing", "a_attr": {"href": "MistakeProofing.html"} , "icon": "icon-1" },{ "id": "FM3format", "parent" : "TASEditorInside", "text": "FM3 format", "a_attr": {"href": "FM3format.html"} , "icon": "icon-1" }] \ No newline at end of file diff --git a/web/help/taseditor/_translations.js b/web/help/taseditor/_translations.js new file mode 100644 index 00000000..36b7fded --- /dev/null +++ b/web/help/taseditor/_translations.js @@ -0,0 +1,11 @@ + +function hnd_ut(a){ +a.TRANSLATIONS['Search term too short'] = "Search term too short"; +a.TRANSLATIONS['No results'] = "No results"; +a.TRANSLATIONS['Please enter 3 or more characters'] = "Please enter 3 or more characters"; +a.TRANSLATIONS['Word list not ready yet. Please wait until the word list is fully downloaded'] = "Word list not ready yet. Please wait until the word list is fully downloaded"; +a.TRANSLATIONS['Incorrect or corrupt search data. Please check your HelpNDoc template'] = "Incorrect or corrupt search data. Please check your HelpNDoc template"; +a.TRANSLATIONS['Related topics...'] = "Related topics..."; +a.TRANSLATIONS['Loading...'] = "Loading..."; +a.TRANSLATIONS['Close'] = "Close"; +} diff --git a/web/help/taseditor/context/0.html b/web/help/taseditor/context/0.html new file mode 100644 index 00000000..37e634ee --- /dev/null +++ b/web/help/taseditor/context/0.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Title" + + + + + + + + diff --git a/web/help/taseditor/context/1.html b/web/help/taseditor/context/1.html new file mode 100644 index 00000000..2f62a68e --- /dev/null +++ b/web/help/taseditor/context/1.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Beginner's Guide" + + + + + + + + diff --git a/web/help/taseditor/context/10.html b/web/help/taseditor/context/10.html new file mode 100644 index 00000000..fc92c752 --- /dev/null +++ b/web/help/taseditor/context/10.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "4.1. Traditional TASing" + + + + + + + + diff --git a/web/help/taseditor/context/11.html b/web/help/taseditor/context/11.html new file mode 100644 index 00000000..a319ab0c --- /dev/null +++ b/web/help/taseditor/context/11.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "4.2. Nonlinear TASing" + + + + + + + + diff --git a/web/help/taseditor/context/12.html b/web/help/taseditor/context/12.html new file mode 100644 index 00000000..328e1fd2 --- /dev/null +++ b/web/help/taseditor/context/12.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "4.3. Semiautomatic TASing" + + + + + + + + diff --git a/web/help/taseditor/context/13.html b/web/help/taseditor/context/13.html new file mode 100644 index 00000000..200048dc --- /dev/null +++ b/web/help/taseditor/context/13.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "5. Program customization" + + + + + + + + diff --git a/web/help/taseditor/context/14.html b/web/help/taseditor/context/14.html new file mode 100644 index 00000000..fb125478 --- /dev/null +++ b/web/help/taseditor/context/14.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "6. Advanced Features" + + + + + + + + diff --git a/web/help/taseditor/context/15.html b/web/help/taseditor/context/15.html new file mode 100644 index 00000000..636ac90c --- /dev/null +++ b/web/help/taseditor/context/15.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Glossary" + + + + + + + + diff --git a/web/help/taseditor/context/16.html b/web/help/taseditor/context/16.html new file mode 100644 index 00000000..d01ea3c9 --- /dev/null +++ b/web/help/taseditor/context/16.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "FAQ" + + + + + + + + diff --git a/web/help/taseditor/context/17.html b/web/help/taseditor/context/17.html new file mode 100644 index 00000000..c81643fa --- /dev/null +++ b/web/help/taseditor/context/17.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Controls" + + + + + + + + diff --git a/web/help/taseditor/context/18.html b/web/help/taseditor/context/18.html new file mode 100644 index 00000000..f08c7202 --- /dev/null +++ b/web/help/taseditor/context/18.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Navigation" + + + + + + + + diff --git a/web/help/taseditor/context/19.html b/web/help/taseditor/context/19.html new file mode 100644 index 00000000..9fedaf3e --- /dev/null +++ b/web/help/taseditor/context/19.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Operations" + + + + + + + + diff --git a/web/help/taseditor/context/2.html b/web/help/taseditor/context/2.html new file mode 100644 index 00000000..2ff3c0f3 --- /dev/null +++ b/web/help/taseditor/context/2.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Reference" + + + + + + + + diff --git a/web/help/taseditor/context/20.html b/web/help/taseditor/context/20.html new file mode 100644 index 00000000..50632950 --- /dev/null +++ b/web/help/taseditor/context/20.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Lua API" + + + + + + + + diff --git a/web/help/taseditor/context/21.html b/web/help/taseditor/context/21.html new file mode 100644 index 00000000..bedf0578 --- /dev/null +++ b/web/help/taseditor/context/21.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Speedrunning synopsis" + + + + + + + + diff --git a/web/help/taseditor/context/22.html b/web/help/taseditor/context/22.html new file mode 100644 index 00000000..f7964360 --- /dev/null +++ b/web/help/taseditor/context/22.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Ideas" + + + + + + + + diff --git a/web/help/taseditor/context/24.html b/web/help/taseditor/context/24.html new file mode 100644 index 00000000..4721e3b0 --- /dev/null +++ b/web/help/taseditor/context/24.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Implementation" + + + + + + + + diff --git a/web/help/taseditor/context/25.html b/web/help/taseditor/context/25.html new file mode 100644 index 00000000..fac966c2 --- /dev/null +++ b/web/help/taseditor/context/25.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "Mistake-proofing" + + + + + + + + diff --git a/web/help/taseditor/context/26.html b/web/help/taseditor/context/26.html new file mode 100644 index 00000000..1c8581a8 --- /dev/null +++ b/web/help/taseditor/context/26.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "FM3 format" + + + + + + + + diff --git a/web/help/taseditor/context/3.html b/web/help/taseditor/context/3.html new file mode 100644 index 00000000..e31aaf2b --- /dev/null +++ b/web/help/taseditor/context/3.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "TAS Editor Inside" + + + + + + + + diff --git a/web/help/taseditor/context/4.html b/web/help/taseditor/context/4.html new file mode 100644 index 00000000..e2d1aa82 --- /dev/null +++ b/web/help/taseditor/context/4.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "1. Introduction" + + + + + + + + diff --git a/web/help/taseditor/context/5.html b/web/help/taseditor/context/5.html new file mode 100644 index 00000000..264c5e81 --- /dev/null +++ b/web/help/taseditor/context/5.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "2. Program Interface" + + + + + + + + diff --git a/web/help/taseditor/context/6.html b/web/help/taseditor/context/6.html new file mode 100644 index 00000000..2a6d1057 --- /dev/null +++ b/web/help/taseditor/context/6.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "2.1. Piano Roll" + + + + + + + + diff --git a/web/help/taseditor/context/7.html b/web/help/taseditor/context/7.html new file mode 100644 index 00000000..2d36e81b --- /dev/null +++ b/web/help/taseditor/context/7.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "2.2. Toolbox" + + + + + + + + diff --git a/web/help/taseditor/context/8.html b/web/help/taseditor/context/8.html new file mode 100644 index 00000000..1103640a --- /dev/null +++ b/web/help/taseditor/context/8.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "3. TASing Process" + + + + + + + + diff --git a/web/help/taseditor/context/9.html b/web/help/taseditor/context/9.html new file mode 100644 index 00000000..37cecd15 --- /dev/null +++ b/web/help/taseditor/context/9.html @@ -0,0 +1,14 @@ + + + + + + Redirecting to "4. TASing Methodology" + + + + + + + + diff --git a/web/help/taseditor/css/effects.min.css b/web/help/taseditor/css/effects.min.css new file mode 100644 index 00000000..37f33b1a --- /dev/null +++ b/web/help/taseditor/css/effects.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */header{transition:top 0.3s ease, padding-left 0.3s ease}div#main{transition:margin-left 0.3s ease}nav{transition:left 0.3s ease, margin-top 0.3s ease, opacity 0.3s ease}.mask{transition:visibility 0s, opacity 0.3s ease}.tab-tabs>li::after{transition:transform 250ms ease 0s}#hnd-splitter{transition:background-color 0.15s linear} diff --git a/web/help/taseditor/css/hnd.content.css b/web/help/taseditor/css/hnd.content.css new file mode 100644 index 00000000..ce204088 --- /dev/null +++ b/web/help/taseditor/css/hnd.content.css @@ -0,0 +1,600 @@ +/* ========== Text Styles ========== */ +hr { color: #000000} +.main-content, .main-content table span.rvts0 /* Normal text */ +{ + font-size: 10pt; + font-family: 'Arial', 'Helvetica', sans-serif; + font-style: normal; + font-weight: normal; + color: #000000; + text-decoration: none; +} +span.rvts1 /* Heading */ +{ + font-weight: bold; + color: #0000ff; +} +span.rvts2 /* Subheading */ +{ + font-weight: bold; + color: #000080; +} +span.rvts3 /* Keywords */ +{ + font-style: italic; + color: #800000; +} +a.rvts4, span.rvts4 /* Jump 1 */ +{ + color: #008000; + text-decoration: underline; +} +a.rvts5, span.rvts5 /* Jump 2 */ +{ + color: #008000; + text-decoration: underline; +} +span.rvts6 +{ +} +span.rvts7 +{ + font-size: 14pt; + font-weight: bold; + color: #365f91; +} +span.rvts8 +{ + font-size: 24pt; + font-weight: bold; +} +span.rvts9 +{ + font-size: 12pt; +} +span.rvts10 +{ + font-size: 14pt; +} +a.rvts11, span.rvts11 +{ + font-size: 12pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts11:hover +{ + color: #0000ff; +} +a.rvts12, span.rvts12 +{ + font-size: 12pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts12:hover +{ + color: #0000ff; +} +span.rvts13 +{ + font-size: 9pt; +} +a.rvts14, span.rvts14 +{ + font-size: 14pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts14:hover +{ + color: #0000ff; +} +a.rvts15, span.rvts15 +{ + font-size: 14pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts15:hover +{ + color: #0000ff; +} +span.rvts16 /* Font Style */ +{ + font-family: 'Tahoma', 'Geneva', sans-serif; + font-style: italic; + color: #c0c0c0; +} +a.rvts17, span.rvts17 /* Font Style */ +{ + font-family: 'Tahoma', 'Geneva', sans-serif; + font-style: italic; + color: #6666ff; + text-decoration: underline; +} +span.rvts18 +{ + font-size: 24pt; + text-decoration: underline; +} +span.rvts19 +{ + font-size: 11pt; + font-family: 'Courier New', 'Courier', monospace; + color: #000080; +} +span.rvts20 +{ + font-size: 11pt; +} +span.rvts21 +{ + font-size: 12pt; + font-weight: bold; +} +span.rvts22 +{ + font-size: 11pt; + font-weight: bold; +} +span.rvts23 +{ + font-size: 11pt; + font-weight: bold; + color: #0096bb; +} +a.rvts24, span.rvts24 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts24:hover +{ + color: #0000ff; +} +a.rvts25, span.rvts25 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts25:hover +{ + color: #0000ff; +} +span.rvts26 +{ + font-size: 11pt; + font-weight: bold; + color: #008817; +} +span.rvts27 +{ + font-size: 11pt; + color: #c10031; +} +a.rvts28, span.rvts28 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts28:hover +{ + color: #0000ff; +} +a.rvts29, span.rvts29 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts29:hover +{ + color: #0000ff; +} +a.rvts30, span.rvts30 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts30:hover +{ + color: #0000ff; +} +span.rvts31 +{ + font-size: 11pt; + text-decoration: underline; +} +a.rvts32, span.rvts32 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts32:hover +{ + color: #0000ff; +} +span.rvts33 +{ + font-size: 11pt; + font-style: italic; +} +a.rvts34, span.rvts34 +{ + font-size: 11pt; + color: #0000ff; + text-decoration: underline; +} +a.rvts34:hover +{ + color: #0000ff; +} +span.rvts35 +{ + font-size: 9pt; + font-weight: bold; +} +span.rvts36 +{ + font-size: 11pt; + font-weight: bold; + color: #008817; + text-decoration: underline; +} +span.rvts37 +{ + font-weight: bold; +} +a.rvts38, span.rvts38 +{ + font-size: 11pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts38:hover +{ + color: #0000ff; +} +a.rvts39, span.rvts39 +{ + font-size: 11pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts39:hover +{ + color: #0000ff; +} +a.rvts40, span.rvts40 +{ + font-size: 11pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts40:hover +{ + color: #0000ff; +} +span.rvts41 +{ + font-size: 11pt; + color: #4f81bd; +} +span.rvts42 +{ + color: #004000; +} +a.rvts43, span.rvts43 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts43:hover +{ + color: #0000ff; +} +span.rvts44 +{ + font-size: 6pt; +} +span.rvts45 +{ + font-size: 16pt; + text-decoration: underline; +} +span.rvts46 +{ + color: #000000; +} +span.rvts47 +{ + font-size: 11pt; + font-weight: bold; + color: #000000; +} +a.rvts48, span.rvts48 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts48:hover +{ + color: #0000ff; +} +a.rvts49, span.rvts49 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts49:hover +{ + color: #0000ff; +} +a.rvts50, span.rvts50 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts50:hover +{ + color: #0000ff; +} +a.rvts51, span.rvts51 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts51:hover +{ + color: #0000ff; +} +a.rvts52, span.rvts52 +{ + color: #0000ff; + text-decoration: underline; +} +a.rvts52:hover +{ + color: #0000ff; +} +span.rvts53 +{ + font-weight: bold; + color: #0000ff; +} +span.rvts54 +{ + font-weight: bold; + color: #000080; +} +span.rvts55 +{ + font-style: italic; + color: #800000; +} +a.rvts56, span.rvts56 +{ + color: #008000; + text-decoration: underline; +} +span.rvts57 +{ + font-size: 11pt; + color: #0a8200; +} +span.rvts58 +{ + font-size: 11pt; + color: #000000; +} +span.rvts59 +{ + font-weight: bold; + color: #ffffff; +} +a.rvts60, span.rvts60 +{ + font-size: 9pt; + font-weight: bold; + color: #0000ff; + text-decoration: underline; +} +a.rvts60:hover +{ + color: #0000ff; +} +span.rvts61 +{ + font-size: 12pt; + font-family: 'Courier New', 'Courier', monospace; + color: #000080; +} +span.rvts62 +{ + font-size: 11pt; + font-style: italic; + color: #243f60; +} +span.rvts63 +{ + font-size: 11pt; + color: #333399; +} +span.rvts64 +{ + font-size: 11pt; + font-style: italic; + font-weight: bold; +} +a.rvts65, span.rvts65 +{ + font-weight: bold; + color: #ffffff; + text-decoration: underline; +} +a.rvts65:hover +{ + color: #0000ff; +} +span.rvts66 +{ + color: #ffffff; +} +span.rvts67 +{ + color: #333399; +} +/* ========== Para Styles ========== */ +p,ul,ol /* Paragraph Style */ +{ + text-align: left; + text-indent: 0px; + padding: 0px 0px 0px 0px; + margin: 0px 0px 0px 0px; +} +.rvps1 /* Centered */ +{ + text-align: center; +} +.rvps2 +{ +} +.rvps3 +{ + text-align: center; +} +.rvps4 +{ + text-align: center; + margin: 4px 0px 0px 0px; +} +.rvps5 +{ + text-align: center; + line-height: 21px; + margin: 0px 0px 10px 0px; +} +.rvps6 /* Paragraph Style */ +{ + text-align: center; + border-color: #c0c0c0; + border-style: solid; + border-width: 1px; + border-right: none; + border-left: none; + padding: 2px 0px 2px 0px; + margin: 7px 0px 7px 0px; +} +.rvps7 +{ + text-align: justify; + text-justify: inter-word; + text-align-last: auto; + text-indent: 30px; +} +.rvps8 +{ + text-indent: 20px; + margin: 8px 0px 0px 30px; +} +.rvps9 +{ + text-indent: 30px; +} +.rvps10 +{ + text-align: justify; + text-align-last: auto; + text-indent: 30px; + padding: 0px 0px 0px 0px; + margin: 0px 0px 0px 0px; +} +.rvps11 +{ + text-indent: 30px; + margin: 0px 0px 6px 0px; +} +.rvps12 +{ + text-align: right; +} +.rvps13 +{ + text-align: center; + text-indent: 30px; +} +.rvps14 +{ + margin: 0px 0px 0px 50px; +} +.rvps15 +{ + text-align: justify; + text-justify: inter-word; + text-align-last: auto; +} +.rvps16 +{ + text-align: justify; + text-justify: inter-word; + text-align-last: auto; + margin: 0px 0px 0px 50px; +} +.rvps17 +{ + text-align: justify; + text-justify: inter-word; + text-align-last: auto; + text-indent: 20px; +} +.rvps18 +{ + text-indent: 30px; + margin: 0px 0px 0px 30px; +} +.rvps19 +{ + text-align: justify; + text-justify: inter-word; + text-align-last: auto; + text-indent: 30px; + margin: 0px 0px 0px 30px; +} +/* ========== Lists ========== */ +.list0 {text-indent: 30px; padding: 0; margin: 0 0 0 0px; list-style-position: inside; list-style-type: decimal;} +.list1 {text-indent: 0px; padding: 0; margin: 0 0 0 72px; list-style-position: outside; list-style-type: decimal;} +.list2 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: decimal;} +.list3 {text-indent: 30px; padding: 0; margin: 0 0 0 0px; list-style-position: inside; list-style-type: disc;} +.list4 {text-indent: 0px; padding: 0; margin: 0 0 0 72px; list-style-position: outside; list-style-type: circle;} +.list5 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: square;} +.list6 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: disc;} +.list7 {text-indent: 0px; padding: 0; margin: 0 0 0 48px; list-style-position: outside; list-style-type: circle;} +.list8 {text-indent: 0px; padding: 0; margin: 0 0 0 72px; list-style-position: outside; list-style-type: square;} +.list9 {text-indent: 0px; padding: 0; margin: 0 0 0 50px; list-style-position: outside;} +.list10 {text-indent: 0px; padding: 0; margin: 0 0 0 22px; list-style-position: outside; list-style-type: square;} +.list11 {text-indent: 0px; padding: 0; margin: 0 0 0 55px; list-style-position: outside; list-style-type: disc;} +.list12 {text-indent: 0px; padding: 0; margin: 0 0 0 17px; list-style-position: outside; list-style-type: circle;} +.list13 {text-indent: 32px; padding: 0; margin: 0 0 0 20px; list-style-position: inside; list-style-type: decimal;} +.list14 {text-indent: 0px; padding: 0; margin: 0 0 0 52px; list-style-position: outside; list-style-type: decimal;} +.list15 {text-indent: 25px; padding: 0; margin: 0 0 0 5px; list-style-position: inside; list-style-type: disc;} +.list16 {text-indent: 0px; padding: 0; margin: 0 0 0 67px; list-style-position: outside; list-style-type: circle;} +.list17 {text-indent: 30px; padding: 0; margin: 0 0 0 40px; list-style-position: inside; list-style-type: disc;} +.list18 {text-indent: 0px; padding: 0; margin: 0 0 0 32px; list-style-position: outside; list-style-type: circle;} +.list19 {text-indent: 30px; padding: 0; margin: 0 0 0 40px; list-style-position: inside; list-style-type: decimal;} +.list20 {text-indent: 0px; padding: 0; margin: 0 0 0 32px; list-style-position: outside; list-style-type: decimal;} +.list21 {text-indent: 30px; padding: 0; margin: 0 0 0 70px; list-style-position: inside; list-style-type: disc;} +.list22 {text-indent: 0px; padding: 0; margin: 0 0 0 2px; list-style-position: outside; list-style-type: circle;} +.list23 {text-indent: 60px; padding: 0; margin: 0 0 0 0px; list-style-position: inside; list-style-type: disc;} diff --git a/web/help/taseditor/css/layout.min.css b/web/help/taseditor/css/layout.min.css new file mode 100644 index 00000000..5efef0ea --- /dev/null +++ b/web/help/taseditor/css/layout.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */.unselectable{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.element-invisible{position:absolute !important;clip:rect(1px, 1px, 1px, 1px);overflow:hidden;height:1px}body{background-color:#fff}@media screen and (max-width: 768px){body.sm-nav-expanded{overflow:hidden}}@media screen and (max-width: 768px){body.sm-nav-expanded nav{left:0;opacity:1}}@media screen and (max-width: 768px){body.sm-nav-expanded .mask{visibility:visible;opacity:0.5}}@media screen and (max-width: 768px){body.sm-nav-expanded .header-up nav{margin-top:0}}@media screen and (min-width: 769px){body.md-nav-expanded div#main{margin-left:350px}}@media screen and (min-width: 769px){body.md-nav-expanded header{padding-left:364px}}@media screen and (min-width: 769px){body.md-nav-expanded nav{left:0;opacity:1}}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#285f8f;text-decoration:underline}header{background-color:#fff;border-bottom:1px solid #d9d9d9;box-shadow:0 1px 5px rgba(0,0,0,0.1);padding:10px 14px;position:fixed;top:0;left:0;right:0;height:64px;min-height:64px;z-index:2;display:flex;flex-wrap:nowrap;align-content:flex-start;align-items:center}@media screen and (max-width: 768px){header.slideUp.headroom--not-bottom{box-shadow:none;top:-64px}}header .hnd-toggle{background-color:transparent;border-color:transparent;margin-right:10px;padding:9px}@media screen and (min-width: 769px){header .hnd-toggle{display:none}}header .hnd-toggle .icon-bar{background-color:#666;display:block;width:22px;height:2px;border-radius:1px}header .hnd-toggle .icon-bar+.icon-bar{margin-top:4px}header h1{margin:0;flex-grow:1;font-size:19px;font-weight:500;line-height:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}header .logo{margin-left:10px;max-height:44px}nav{background-color:#f7f7f7;border:0;opacity:0;position:fixed;top:0;left:-350px;bottom:0;width:350px;z-index:3;overflow:hidden;display:flex;flex-direction:column;flex-wrap:nowrap}@media screen and (max-width: 768px){nav{box-shadow:1px 0 5px rgba(0,0,0,0.1);left:-90%;width:90% !important;margin-top:0;z-index:5}}nav .tab-tabs{border-bottom:1px solid #d9d9d9;box-shadow:0 1px 5px rgba(0,0,0,0.1);display:flex;justify-content:space-around;align-items:stretch;height:64px;min-height:64px;margin:0;padding:0}nav .tab-tabs .hnd-toggle{background-color:#eaeaea;margin:0 16px 0 14px;padding:6px 13px}nav .tab-tabs .hnd-toggle:hover{background-color:#f7f7f7}@media screen and (min-width: 769px){nav .tab-tabs .hnd-toggle{display:none}}nav .tab-tabs li{font-size:16px;height:100%;list-style:none;overflow:hidden;position:relative;text-align:center;float:none;margin-bottom:0}nav .tab-tabs li a{min-height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;align-content:stretch;text-overflow:ellipsis;cursor:pointer !important;border:0 !important;border-color:transparent !important;border-radius:0 !important;margin:0 !important;padding:0 !important;line-height:initial !important}nav .tab-tabs li .glyphicon{margin-bottom:5px}nav .tab-tabs li#nav-close{align-self:center;height:auto;min-width:70px}@media screen and (min-width: 769px){nav .tab-tabs li#nav-close{min-width:0}}nav .tab-tabs li+li{flex-grow:1}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#ddd;color:#337ab7}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#eaeaea;color:#337ab7}nav .tab-tabs>li.tab::after{content:"";background:#337ab7;height:2px;position:absolute;width:100%;left:0;bottom:0;transform:scale(0)}nav .tab-tabs>li.tab.active::after,nav .tab-tabs>li.tab:hover::after{transform:scale(1)}nav .tab-tabs>li.active>a{background-color:#f2f2f2}nav .tab-content{flex-grow:1;overflow:auto}nav .search-input{margin:7px}@media screen and (max-width: 768px){nav .search-input #input-search{font-size:16px}}nav #search-info{border-left:2px solid #ddd;display:none;margin:7px;padding:5px}@media screen and (max-width: 768px){nav #search-info{font-size:16px}}#hnd-splitter{background-color:transparent;position:fixed;top:0;left:-100px;width:8px;height:100%;touch-action:none;user-select:none;z-index:10}#hnd-splitter:hover{background-color:#ddd}@media screen and (max-width: 768px){#hnd-splitter{display:none}}.mask{background-color:#000;visibility:hidden;opacity:0;position:fixed;top:0;left:0;right:0;bottom:0;z-index:4}div#main{margin:64px 0 0 0;z-index:1}div#main>article{padding:14px}div#main>article mark{background-color:#ffff7b;padding:0}div#main>article .navigation{border-bottom:2px solid #f2f2f2;display:flex;margin-bottom:20px}div#main>article .navigation:empty{border:0}div#main>article .navigation .breadcrumb{background-color:transparent;border-radius:0;flex-grow:1;margin-bottom:0;padding:0 0 5px 0}div#main>article .navigation .breadcrumb>li::after{padding:0 5px;color:#d9d9d9;content:"/"}div#main>article .navigation .breadcrumb>li+li::before{content:none;padding:0}div#main>article .navigation .nav-arrows{flex-shrink:0;margin-bottom:4px}div#main>article .navigation .nav-arrows a{border:0;background-color:transparent;color:#333;padding:1px 6px}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#337ab7}div#main>article #topic_footer{margin-top:14px}#topic-content{padding:0}#topic-content table{border-collapse:separate}#topic-content img{max-width:100%;height:auto;vertical-align:baseline}.jstree .jstree-anchor{text-shadow:inherit}.jstree .jstree-node .jstree-clicked{background:#ddd;border-color:#aaa}.jstree .jstree-node .jstree-hovered{background:#eaeaea;border-color:#b7b7b7}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl{background-color:transparent;background-image:none;background-position:0 0}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{content:"\e250";color:#666;font-family:'Glyphicons Halflings';font-style:normal;font-size:10px}@media screen and (max-width: 768px){.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{font-size:16px}}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#337ab7}.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{content:"\e252"}.jstree .jstree-node.jstree-open>.jstree-anchor>.icon-default{background:transparent url(../vendors/helpndoc-5/icons/1.png) no-repeat center center !important}.jstree .jstree-node.jstree-closed>.jstree-anchor>.icon-default{background:transparent url(../vendors/helpndoc-5/icons/0.png) no-repeat center center !important}.jstree .jstree-node .icon-default{background:transparent url(../vendors/helpndoc-5/icons/8.png) no-repeat center center !important}.jstree .jstree-node .icon-0{background:transparent url(../vendors/helpndoc-5/icons/0.png) no-repeat center center !important}.jstree .jstree-node .icon-1{background:transparent url(../vendors/helpndoc-5/icons/1.png) no-repeat center center !important}.jstree .jstree-node .icon-2{background:transparent url(../vendors/helpndoc-5/icons/2.png) no-repeat center center !important}.jstree .jstree-node .icon-3{background:transparent url(../vendors/helpndoc-5/icons/3.png) no-repeat center center !important}.jstree .jstree-node .icon-4{background:transparent url(../vendors/helpndoc-5/icons/4.png) no-repeat center center !important}.jstree .jstree-node .icon-5{background:transparent url(../vendors/helpndoc-5/icons/5.png) no-repeat center center !important}.jstree .jstree-node .icon-6{background:transparent url(../vendors/helpndoc-5/icons/6.png) no-repeat center center !important}.jstree .jstree-node .icon-7{background:transparent url(../vendors/helpndoc-5/icons/7.png) no-repeat center center !important}.jstree .jstree-node .icon-8{background:transparent url(../vendors/helpndoc-5/icons/8.png) no-repeat center center !important}.jstree .jstree-node .icon-9{background:transparent url(../vendors/helpndoc-5/icons/9.png) no-repeat center center !important}.jstree .jstree-node .icon-10{background:transparent url(../vendors/helpndoc-5/icons/10.png) no-repeat center center !important}.jstree .jstree-node .icon-11{background:transparent url(../vendors/helpndoc-5/icons/11.png) no-repeat center center !important}.jstree .jstree-node .icon-12{background:transparent url(../vendors/helpndoc-5/icons/12.png) no-repeat center center !important}.jstree .jstree-node .icon-13{background:transparent url(../vendors/helpndoc-5/icons/13.png) no-repeat center center !important}.jstree .jstree-node .icon-14{background:transparent url(../vendors/helpndoc-5/icons/14.png) no-repeat center center !important}.jstree .jstree-node .icon-15{background:transparent url(../vendors/helpndoc-5/icons/15.png) no-repeat center center !important}.jstree .jstree-node .icon-16{background:transparent url(../vendors/helpndoc-5/icons/16.png) no-repeat center center !important}.jstree .jstree-node .icon-17{background:transparent url(../vendors/helpndoc-5/icons/17.png) no-repeat center center !important}.jstree .jstree-node .icon-18{background:transparent url(../vendors/helpndoc-5/icons/18.png) no-repeat center center !important}.jstree .jstree-node .icon-19{background:transparent url(../vendors/helpndoc-5/icons/19.png) no-repeat center center !important}.jstree .jstree-node .icon-20{background:transparent url(../vendors/helpndoc-5/icons/20.png) no-repeat center center !important}.jstree .jstree-node .icon-21{background:transparent url(../vendors/helpndoc-5/icons/21.png) no-repeat center center !important}.jstree .jstree-node .icon-22{background:transparent url(../vendors/helpndoc-5/icons/22.png) no-repeat center center !important}.jstree .jstree-node .icon-23{background:transparent url(../vendors/helpndoc-5/icons/23.png) no-repeat center center !important}.jstree .jstree-node .icon-24{background:transparent url(../vendors/helpndoc-5/icons/24.png) no-repeat center center !important}.jstree .jstree-node .icon-25{background:transparent url(../vendors/helpndoc-5/icons/25.png) no-repeat center center !important}.jstree .jstree-node .icon-26{background:transparent url(../vendors/helpndoc-5/icons/26.png) no-repeat center center !important}.jstree .jstree-node .icon-27{background:transparent url(../vendors/helpndoc-5/icons/27.png) no-repeat center center !important}.jstree .jstree-node .icon-28{background:transparent url(../vendors/helpndoc-5/icons/28.png) no-repeat center center !important}.jstree .jstree-node .icon-29{background:transparent url(../vendors/helpndoc-5/icons/29.png) no-repeat center center !important}.jstree .jstree-node .icon-30{background:transparent url(../vendors/helpndoc-5/icons/30.png) no-repeat center center !important}.jstree .jstree-node .icon-31{background:transparent url(../vendors/helpndoc-5/icons/31.png) no-repeat center center !important}.jstree .jstree-node .icon-32{background:transparent url(../vendors/helpndoc-5/icons/32.png) no-repeat center center !important}.jstree .jstree-node .icon-33{background:transparent url(../vendors/helpndoc-5/icons/33.png) no-repeat center center !important}.jstree .jstree-node .icon-34{background:transparent url(../vendors/helpndoc-5/icons/34.png) no-repeat center center !important}.jstree .jstree-node .icon-35{background:transparent url(../vendors/helpndoc-5/icons/35.png) no-repeat center center !important}.jstree .jstree-node .icon-36{background:transparent url(../vendors/helpndoc-5/icons/36.png) no-repeat center center !important}.jstree .jstree-node .icon-37{background:transparent url(../vendors/helpndoc-5/icons/37.png) no-repeat center center !important}.jstree .jstree-node .icon-38{background:transparent url(../vendors/helpndoc-5/icons/38.png) no-repeat center center !important}.jstree .jstree-node .icon-39{background:transparent url(../vendors/helpndoc-5/icons/39.png) no-repeat center center !important}.jstree .jstree-node .icon-40{background:transparent url(../vendors/helpndoc-5/icons/40.png) no-repeat center center !important}.jstree .jstree-node .icon-41{background:transparent url(../vendors/helpndoc-5/icons/41.png) no-repeat center center !important}.modal-body .relative-list{margin:0;padding:5px}.modal-body .relative-list li{list-style:none;margin:0;padding:0}@media screen and (max-width: 768px){.modal-body .relative-list li{font-size:1.1em;font-weight:700}}.modal-body .relative-list li a{color:#333;display:block;padding:5px}@media screen and (max-width: 768px){.modal-body .relative-list li a{padding:10px}}.modal-body .relative-list li a:hover{background-color:#f2f2f2;text-decoration:none} diff --git a/web/help/taseditor/css/print.min.css b/web/help/taseditor/css/print.min.css new file mode 100644 index 00000000..630764a7 --- /dev/null +++ b/web/help/taseditor/css/print.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */header,nav,footer{display:none}div#main{margin:0}div#main>article .navigation{border-bottom:1px solid #aaa}div#main>article .navigation .nav-arrows{display:none} diff --git a/web/help/taseditor/css/theme-dark-blue.min.css b/web/help/taseditor/css/theme-dark-blue.min.css new file mode 100644 index 00000000..eb58d757 --- /dev/null +++ b/web/help/taseditor/css/theme-dark-blue.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#3598dc}a:focus,a:hover{color:#1d6fa7}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#3598dc}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#3598dc}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#3598dc}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#3598dc}nav .tab-tabs>li.tab::after{background:#3598dc}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#3598dc}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#3598dc} diff --git a/web/help/taseditor/css/theme-dark-green.min.css b/web/help/taseditor/css/theme-dark-green.min.css new file mode 100644 index 00000000..2da23282 --- /dev/null +++ b/web/help/taseditor/css/theme-dark-green.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#82b440}a:focus,a:hover{color:#597c2c}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#82b440}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#82b440}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#82b440}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#82b440}nav .tab-tabs>li.tab::after{background:#82b440}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#82b440}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#82b440} diff --git a/web/help/taseditor/css/theme-dark-orange.min.css b/web/help/taseditor/css/theme-dark-orange.min.css new file mode 100644 index 00000000..ce791959 --- /dev/null +++ b/web/help/taseditor/css/theme-dark-orange.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#f40}a:focus,a:hover{color:#b33000}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#f40}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#f40}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#f40}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#f40}nav .tab-tabs>li.tab::after{background:#f40}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#f40}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#f40} diff --git a/web/help/taseditor/css/theme-dark-purple.min.css b/web/help/taseditor/css/theme-dark-purple.min.css new file mode 100644 index 00000000..3e3eb127 --- /dev/null +++ b/web/help/taseditor/css/theme-dark-purple.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#D400FF}a:focus,a:hover{color:#9400b3}header{background-color:#333;border-bottom-color:#1a1a1a;color:#eee}header .hnd-toggle .icon-bar{background-color:#fff}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#D400FF}nav{background-color:#333}nav .tab-tabs{border-bottom-color:#1a1a1a}nav .tab-tabs .hnd-toggle{background-color:#2e2e2e;border-color:#1a1a1a;color:#eee}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#292929;border-color:#0f0f0f;color:#D400FF}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#eee}nav .tab-tabs>li.active>a{background-color:#2e2e2e;color:#D400FF}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#292929;color:#D400FF}nav .tab-tabs>li.tab::after{background:#D400FF}nav #search-info{border-left-color:#eee;color:#eee}.jstree .jstree-anchor{color:#eee}.jstree .jstree-node .jstree-clicked{background-color:#1f1f1f;border-color:#121212}.jstree .jstree-node .jstree-hovered{background-color:#141414;border-color:#080808}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#eee}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#D400FF}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#333}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#D400FF} diff --git a/web/help/taseditor/css/theme-light-blue.min.css b/web/help/taseditor/css/theme-light-blue.min.css new file mode 100644 index 00000000..795008c7 --- /dev/null +++ b/web/help/taseditor/css/theme-light-blue.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#337ab7}a:focus,a:hover{color:#22527b}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#337ab7}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#337ab7}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#337ab7}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#337ab7}nav .tab-tabs>li.tab::after{background:#337ab7}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#337ab7}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#337ab7} diff --git a/web/help/taseditor/css/theme-light-green.min.css b/web/help/taseditor/css/theme-light-green.min.css new file mode 100644 index 00000000..7e7bbe97 --- /dev/null +++ b/web/help/taseditor/css/theme-light-green.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#6f9a37}a:focus,a:hover{color:#466223}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#6f9a37}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#6f9a37}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#6f9a37}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#6f9a37}nav .tab-tabs>li.tab::after{background:#6f9a37}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#6f9a37}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#6f9a37} diff --git a/web/help/taseditor/css/theme-light-orange.min.css b/web/help/taseditor/css/theme-light-orange.min.css new file mode 100644 index 00000000..a754af0f --- /dev/null +++ b/web/help/taseditor/css/theme-light-orange.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#B23000}a:focus,a:hover{color:#661b00}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#B23000}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#B23000}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#B23000}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#B23000}nav .tab-tabs>li.tab::after{background:#B23000}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#B23000}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#B23000} diff --git a/web/help/taseditor/css/theme-light-purple.min.css b/web/help/taseditor/css/theme-light-purple.min.css new file mode 100644 index 00000000..f4bb2c60 --- /dev/null +++ b/web/help/taseditor/css/theme-light-purple.min.css @@ -0,0 +1,5 @@ +/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */a{color:#9400B2}a:focus,a:hover{color:#540066}header{background-color:#fff;border-bottom-color:#e6e6e6;color:#222}header .hnd-toggle .icon-bar{background-color:#6f6f6f}header .hnd-toggle.active,header .hnd-toggle:active,header .hnd-toggle.focus,header .hnd-toggle:focus,header .hnd-toggle:active:focus,header .hnd-toggle:hover{background-color:#f5f5f5;border-color:#dbdbdb}header .hnd-toggle.active .icon-bar,header .hnd-toggle:active .icon-bar,header .hnd-toggle.focus .icon-bar,header .hnd-toggle:focus .icon-bar,header .hnd-toggle:active:focus .icon-bar,header .hnd-toggle:hover .icon-bar{background-color:#9400B2}nav{background-color:#f7f7f7}nav .tab-tabs{border-bottom-color:#dedede}nav .tab-tabs .hnd-toggle{background-color:#f2f2f2;border-color:#dedede;color:#666}nav .tab-tabs .hnd-toggle.active,nav .tab-tabs .hnd-toggle:active,nav .tab-tabs .hnd-toggle.focus,nav .tab-tabs .hnd-toggle:focus,nav .tab-tabs .hnd-toggle:active:focus,nav .tab-tabs .hnd-toggle:hover{background-color:#ededed;border-color:#d3d3d3;color:#9400B2}nav .tab-tabs>li>a,nav .tab-tabs>li.active>a,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{color:#666}nav .tab-tabs>li.active>a{background-color:#f2f2f2;color:#9400B2}nav .tab-tabs>li>a:focus,nav .tab-tabs>li>a:hover,nav .tab-tabs>li.active>a:focus,nav .tab-tabs>li.active>a:hover{background-color:#ededed;color:#9400B2}nav .tab-tabs>li.tab::after{background:#9400B2}nav #search-info{border-left-color:#666;color:#666}.jstree .jstree-anchor{color:#666}.jstree .jstree-node .jstree-clicked{background-color:#e3e3e3;border-color:#d6d6d6}.jstree .jstree-node .jstree-hovered{background-color:#d8d8d8;border-color:#ccc}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:before{color:#666}.jstree .jstree-node.jstree-closed>.jstree-icon.jstree-ocl:hover:before,.jstree .jstree-node.jstree-open>.jstree-icon.jstree-ocl:hover:before{color:#9400B2}div#main>article .navigation{border-bottom-color:#f2f2f2}div#main>article .navigation .breadcrumb>li::after{color:#ccc}div#main>article .navigation .nav-arrows a{color:#222}div#main>article .navigation .nav-arrows a:hover,div#main>article .navigation .nav-arrows a:focus:hover{color:#9400B2} diff --git a/web/help/taseditor/index.html b/web/help/taseditor/index.html index 13575584..de4c98ec 100644 --- a/web/help/taseditor/index.html +++ b/web/help/taseditor/index.html @@ -1,34 +1,344 @@ - - + + + + - - - TAS Editor Manual - + + + + + + + Title + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + +
      + +

      TAS Editor Manual

      + +
      + + + +
      + +
      +
      + + + + + + +

      Title

      + +
      + +

      +


      +


      +

      TAS Editor 1.01

      +


      +


      +

      Welcome to the TAS Editor Manual!

      +


      +
      + + + + +
      +

      Taseditor is an Integrated development environment dedicated to TASing.

      +

      Playing videogames in Taseditor resembles both interactive programming and drawing notes by mouse in a music editor.

      +
      +
      +


      +
      + + + + + + + + + + + + + + + + +
      +

      Beginner's Guide

      +
      +

      Reference

      +
      +

      TAS Editor Inside

      +
      +

      If you're seeing the Manual for the first time, please study this whole course

      +
      +

      Look here when you need to know comprehensive specifications about limits and possibilities of TAS Editor

      +
      +

      Read these docs when you wish to learn details of the system

      +
      +

      Introduction

      +

      Program Interface

      +

      TASing Process

      +

      TASing Methodology

      +

      Program Customization

      +

      Advanced Features

      +
      +

      Glossary

      +

      Controls

      +

      Navigation

      +

      Operations

      +

      Lua API

      +

      FAQ

      +

      Speedrunning Synopsis

      +
      +

      Ideas

      +

      Implementation

      +

      Mistake-proofing

      +

      FM3 format

      +
      +
      +


      +


      +


      +

      Author of TAS Editor v1.01: AnS

      +

      Assistance in testing: feos

      +


      +

      Author of this Manual: AnS

      +

      English translation: AnS, feos

      +


      +


      +


      +


      +


      +

      +

      Created with the Personal Edition of HelpNDoc: Free PDF documentation generator

      + +
      + + +
      +
      + +
      + +
      + +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/help/taseditor/js/app.min.js b/web/help/taseditor/js/app.min.js new file mode 100644 index 00000000..23236079 --- /dev/null +++ b/web/help/taseditor/js/app.min.js @@ -0,0 +1,6 @@ +"use strict";/*! + * HelpNDoc HTML template + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */ +var __extends=this&&this.__extends||function(){var e=function(t,o){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])})(t,o)};return function(t,o){function n(){this.constructor=t}e(t,o),t.prototype=null===o?Object.create(o):(n.prototype=o.prototype,new n)}}(),Exception=function(e){function t(t){var o=e.call(this,t)||this;return o.message=t,o.name="Exception",o.message=t,o}return __extends(t,e),t.prototype.toString=function(){return"["+this.name+']: "'+this.message+'"'},t}(Error),EInvalidHtmlElement=function(e){function t(t){var o=e.call(this,t)||this;return o.message=t,o.name="EInvalidHtmlElement",o}return __extends(t,e),t}(Exception),Hnd;!function(e){var t=function(){function e(){}return e}();e.AppOptions=t;var o=function(){function e(){}return e}();e.AppEvents=o;var n=function(){function e(e){this.DEFAULTS={animationDelay:200,elHeadroom:"header",elMask:".mask",elModal:"#hndModal",elSearchForm:"#search-form",elSearchInfo:"#search-info",elSearchInput:"#input-search",elToggler:".hnd-toggle",elTopicContainer:"article",elTopicContent:"#topic-content",elTreeContainers:".tree-container",elTreeSearch:"#search-tree",classNavExpandedSmall:"sm-nav-expanded",classNavExpandedMedium:"md-nav-expanded"},this.EVENTS={onTopicChanged:null},this.TRANSLATIONS={"Search term too short":"Search term too short","No results":"No results","Please enter 3 or more characters":"Please enter 3 or more characters","Word list not ready yet. Please wait until the word list is fully downloaded":"Word list not ready yet. Please wait until the word list is fully downloaded","Incorrect or corrupt search data. Please check your HelpNDoc template":"Incorrect or corrupt search data. Please check your HelpNDoc template","Related topics...":"Related topics...","Loading...":"Loading...",Close:"Close"},this.options=$.extend({},this.DEFAULTS,e),this.Init()}return e.prototype._=function(e){var t=this.TRANSLATIONS[e];return t||e},e.prototype.doOnJsTreeError=function(e,t){console.error("JSTree Error",t);var o=e.find(".jstree-loading");o&&(t.error&&"ajax"==t.error?o.html('Loading Error: Please make sure your web-server is correctly configured to serve JSON files. Learn more...'):o.html("Error: please check your web-developer console for more information."))},e.prototype.doOnTopicChanged=function(e){this.EVENTS.onTopicChanged&&("string"==typeof e&&""!==e||(e=$(this.options.elTopicContent).data("hnd-id")+".html"),this.EVENTS.onTopicChanged(e))},e.prototype.doProcessParameters=function(){var e=URI(location.href),t=e.search(!0);t.tab&&""!=t.tab&&$("#tab-"+t.tab).tab("show"),t.search&&void 0!==t.search&&""!=t.search&&(this.$elSearchInput.val(t.search),this.$elSearchInput.keyup(),this.$elSearchForm.submit())},e.prototype.fixURI=function(e){return e.replace(/\%u00A0/g,"%20")},e.prototype.getAnchor=function(){return window.location.hash.substr(1)},e.prototype.isExternalLink=function(e){var t=function(e){return 0===e.indexOf("//")&&(e=location.protocol+e),e.toLowerCase().replace(/([a-z])?:\/\//,"$1").split("/")[0]};return(e.indexOf(":")>-1||e.indexOf("//")>-1)&&t(location.href)!==t(e)||-1==["htm","html"].indexOf(new URI(e).suffix().toLowerCase())},e.prototype.DoShowExternalUrl=function(e,t,o){window.open(t,o)},e.prototype.DoShowTopic=function(e,t,o){var n=this;this.$elTopicContainer.load(o+" "+this.options.elTopicContent,function(e,r,i){var a=$(n.options.elTopicContent),s=a.data("hnd-id");if(window.history.pushState({id:s,title:t},t,o),"undefined"!=typeof ga&&ga)try{if(void 0!==ga.getAll&&ga.getAll&&ga.getAll()[0]){ga.getAll()[0].send("pageview",location.pathname)}else ga("send","pageview",location.pathname)}catch(e){console.error("[HND-APP] An error occurred while using Google Analytics tracking code =>",e.toString())}n.SelectTopicInToc(s,t,!1),n.DoScrollToAnchorIfNeeded(),n.DoHighlightText(n.searchTerm),imageMapResize(),n.doOnTopicChanged(o)})},e.prototype.DoHandleLink=function(e,t,o,n,r){"_blank"==n||this.isExternalLink(o)||!0===r?this.DoShowExternalUrl(t,o,n):this.DoShowTopic(e,t,o)},e.prototype.DoHighlightText=function(e){try{this.$elTopicContainer.unmark(),e&&""!==e&&this.$elTopicContainer.mark(e,{accuracy:"complementary",diacritics:!1})}catch(e){console.error("[HND-APP] An error occurred while highlighting the search term =>",e.toString())}},e.prototype.DoScrollToAnchorIfNeeded=function(){var e=decodeURIComponent(this.getAnchor());if(""!==e){var t=$("a[name='"+e+"']");if(t&&t.length||(t=$("a[name='"+e.toLowerCase()+"']")),t&&void 0!==t&&t.offset&&t.offset()){var o=this.$elHeadroom.position().top<0?0:this.$elHeadroom.outerHeight(!0)+5;$("html,body").animate({scrollTop:t.offset().top-o},"fast")}else console.error("[HND-APP] Unkonwn or invalid anchor =>",e)}else $("html,body").animate({scrollTop:0},"fast")},e.prototype.InitHeadRoom=function(){if(this.$elHeadroom=$(this.options.elHeadroom),!this.$elHeadroom.length)throw new EInvalidHtmlElement("Invalid headroom element ["+this.options.elHeadroom+"]");new Headroom(this.$elHeadroom.get(0),{offset:100,tolerance:5,classes:{initial:"animated",pinned:"slideDown",unpinned:"slideUp"},onUnpin:function(){$("body").addClass("header-up")},onPin:function(){$("body").removeClass("header-up")}}).init()},e.prototype.InitMask=function(){var e=this;this.$elMask=$(this.options.elMask),this.$elMask.on("click",function(t){var o=e.$elMask.data("toggle");o&&$("body").removeClass(o)})},e.prototype.InitModal=function(){this.$elModal=$(this.options.elModal),this.$elModal.find(".modal-title").html(this._("Related topics...")),this.$elModal.find(".modal-btn-close").html(this._("Close")),this.$elModal.modal({show:!1})},e.prototype.InitResponsiveClasses=function(){function e(){var e="",o=$(window).width();if(o<768?e="mode-xs":o<992?e="mode-sm":o<1200?e="mode-md":o>=1200&&(e="mode-lg"),e!=t){if($("body").removeClass(["mode-xs","mode-sm","mode-md","mode-lg"]).addClass(e),"mode-xs"==e)$("header").css("padding-left",""),$("#main").css("margin-left",""),$("#panel-left").css("width","");else if("mode-xs"==t){var n=$("#hnd-splitter").offset().left;$("header").css("padding-left",n+14),$("#main").css("margin-left",n),$("#panel-left").css("width",n)}t=e}}var t="";e(),$(window).on("resize",function(){e()})},e.prototype.InitSplitter=function(){var e=0,t=parseInt($("nav").css("width"),10),o=$("#hnd-splitter");o&&o.length&&interact("#hnd-splitter").draggable({cursorChecker:function(){return"ew-resize"},startAxis:"xy",lockAxis:"x",listeners:{move:function(t){e+=t.dx,t.target.style.transform="translateX("+e+"px)"},end:function(o){$("header").css("padding-left",t+14+e),$("#main").css("margin-left",t+e),$("#panel-left").css("width",t+e)}}})},e.prototype.InitSearchEngine=function(){this.searchEngine=new HndJsSe},e.prototype.InitSearchForm=function(){var e=this;this.$elTreeSearch=$(this.options.elTreeSearch).first(),this.$elSearchForm=$(this.options.elSearchForm),this.$elSearchInfo=$(this.options.elSearchInfo),this.$elSearchInput=$(this.options.elSearchInput),this.$elSearchInfo.html(this._("Please enter 3 or more characters")+"."),this.$elSearchInfo.show(),this.$elSearchInput.on("keyup",function(t){e.searchTerm=String(e.$elSearchInput.val()),e.DoHighlightText(e.searchTerm)}),this.$elSearchForm.on("submit",function(t){t.preventDefault();var o=e.$elTreeSearch.jstree(!0),n=$(t.target).find('input[type="text"]').first(),r=String(n.val());if(e.$elSearchInfo.hide(),o.delete_node(e.$elTreeSearch.find("li").toArray()),r.length<3)e.$elSearchInfo.html(e._("Search term too short")+". "+e._("Please enter 3 or more characters")+"."),e.$elSearchInfo.show();else if(window.bSearchDataLoaded)if(oWl){e.searchEngine.ParseInput(r);var i=e.searchEngine.PerformSearch(oWl);if(0==i.length)e.$elSearchInfo.html(e._("No results")+". "+e._("Please enter 3 or more characters")+"."),e.$elSearchInfo.show();else for(var a="",s=0;s'+c[d].title+"";h+="
    ",e.$elModal.find(".modal-body").html(h),e.$elModal.modal("show")}else $("body").removeClass("sm-nav-expanded"),e.DoHandleLink(a,s,i,l,!1)}}).on("ready.jstree",function(t,n){e.SelectTopicInToc("","",!0);var r=parseInt($(o).data("openlvl"),10);r&&e.OpenTreeToLevel($(o),r)}).jstree({core:{animation:e.options.animationDelay,check_callback:$(o).is($(e.options.elTreeSearch)),multiple:!1,strings:{"Loading ...":e._("Loading...")},themes:{dots:!1,responsive:!0},data:r,error:function(t){e.doOnJsTreeError($(o),t)}},types:{default:{icon:"icon-default"}},plugins:["types"]})})},e.prototype.InitHistory=function(){var e=this;window.onpopstate=function(t){e.$elTopicContainer.load(window.location+" "+e.options.elTopicContent,function(t,o,n){e.SelectTopicInToc("","",!1),e.DoScrollToAnchorIfNeeded()})}},e.prototype.InitLinks=function(){var e=this,t=function(t){t.preventDefault();var o=t.currentTarget;e.$elModal&&e.$elModal.modal("hide"),$("body").removeClass("sm-nav-expanded"),e.DoHandleLink("","",o.href,o.target,!0===t.ctrlKey)};this.$elTopicContainer.on("click","a",t),$(".modal-body").on("click","a",t)},e.prototype.Init=function(){if(this.$elTopicContainer=$(this.options.elTopicContainer),!this.$elTopicContainer)throw new EInvalidHtmlElement("Invalid topic container element ["+this.options.elTopicContainer+"]")},e.prototype.Boot=function(){try{this.InitTrees(),this.InitLinks(),this.InitHistory(),this.InitToggler(),this.InitMask(),this.InitModal(),this.InitSearchEngine(),this.InitSearchForm(),this.InitHeadRoom(),this.InitSplitter(),this.InitResponsiveClasses(),this.doOnTopicChanged(),this.doProcessParameters()}catch(e){console.error("[HND-APP] An error occurred while booting the application =>",e.toString())}},e.prototype.OpenTreeToLevel=function(e,t){try{if(t){var o=$(e).jstree(!0);o&&$(o.get_json("#",{no_a_attr:!0,no_children:!1,no_data:!0,no_id:!1,no_li_attr:!0,no_state:!0,flat:!0})).each(function(e,n){var r=o.get_node($(this).attr("id"));r.parents.length<=t&&o.open_node(r)})}}catch(e){console.error("[HND-APP] An error occurred while opening the tree =>",e.toString())}},e.prototype.SelectTopicInToc=function(e,t,o){void 0===o&&(o=!1),"string"==typeof e&&""!==e||(e=$(this.options.elTopicContent).data("hnd-id")),"string"==typeof t&&""!==t||(t=$(this.options.elTopicContent).data("hnd-title")),"string"==typeof e&&""!==e&&(this.$elTreeContainers.jstree("deselect_all",!0),this.$elTreeContainers.jstree("select_node",e,!0,!1),t&&""!==t&&(document.title=t),o&&setTimeout(function(){var t=document.getElementById(e+"_anchor");t&&t.scrollIntoView()},this.options.animationDelay+50))},e}();e.App=n}(Hnd||(Hnd={})); \ No newline at end of file diff --git a/web/help/taseditor/js/hndsd.min.js b/web/help/taseditor/js/hndsd.min.js new file mode 100644 index 00000000..a8e80037 --- /dev/null +++ b/web/help/taseditor/js/hndsd.min.js @@ -0,0 +1 @@ +var aTl=[['Title.html','Title'],['BeginnersGuide.html','Beginner%27s%20Guide'],['Introduction.html','1%2E%20Introduction'],['ProgramInterface.html','2%2E%20Program%20Interface'],['PianoRoll.html','2%2E1%2E%20Piano%20Roll'],['Toolbox.html','2%2E2%2E%20Toolbox'],['TASingProcess.html','3%2E%20TASing%20Process'],['TASingMethodology.html','4%2E%20TASing%20Methodology'],['TraditionalTASing.html','4%2E1%2E%20Traditional%20TASing'],['NonlinearTASing.html','4%2E2%2E%20Nonlinear%20TASing'],['SemiautomaticTASing.html','4%2E3%2E%20Semiautomatic%20TASing'],['ProgramCustomization.html','5%2E%20Program%20customization'],['AdvancedFeatures.html','6%2E%20Advanced%20Features'],['Reference.html','Reference'],['Glossary.html','Glossary'],['Controls.html','Controls'],['Navigation.html','Navigation'],['Operations.html','Operations'],['LuaAPI.html','Lua%20API'],['FAQ.html','FAQ'],['SpeedrunningSynopsis.html','Speedrunning%20synopsis'],['TASEditorInside.html','TAS%20Editor%20Inside'],['Ideas.html','Ideas'],['Implementation.html','Implementation'],['MistakeProofing.html','Mistake%2Dproofing'],['FM3format.html','FM3%20format']];var oWl=['pointer',[[22,2],[23,5],[4,5],[14,1],[11,2],[5,2]],'cheating',[[2,1]],'really',[[12,1],[10,1],[7,1]],'max',[[22,1],[23,3],[14,1],[11,2],[6,1]],'taser',[[6,10],[20,3],[22,20],[16,1],[2,17],[8,2],[4,4],[10,8],[5,5],[19,1],[14,7],[7,10],[12,5],[11,2]],'suboptimal',[[9,1],[2,1]],'mariowidth',[[12,3]],'formulating',[[23,1]],'saveas',[[24,1]],'soulless',[[9,1]],'base64',[[25,1]],'defines',[[6,1],[11,4],[5,1]],'init',[[23,1]],'intensive',[[22,1]],'fix',[[10,1],[5,1],[7,3],[2,2],[8,1],[9,1],[12,1]],'accelerators',[[22,1]],'commonly',[[12,1]],'handling',[[6,1],[11,1],[2,1]],'control',[[22,7],[4,2],[23,1],[19,1],[2,3],[14,1],[11,1],[12,1]],'reduce',[[2,2]],'modifiers',[[15,2]],'highlight',[[22,1]],'autofire',[[23,1],[2,1],[12,1],[11,1]],'resultant',[[22,1]],'moving',[[22,5],[6,2],[16,3],[15,6],[17,1],[9,1],[24,1],[4,1],[10,2],[5,1],[23,1],[7,1],[11,1],[12,1]],'lead',[[9,1],[15,1]],'video',[[5,5],[14,1],[12,1],[6,1]],'widths',[[23,1]],'anyway',[[12,1],[8,1],[11,2],[6,1]],'inconvenient',[[11,1],[7,1]],'md5',[[24,1],[25,1]],'introduction',[[1,1],[0,1],[2,3]],'intermediate',[[5,1],[22,1],[8,2],[6,2]],'ease',[[13,1],[4,1]],'spot',[[5,1]],'hides',[[22,1],[23,1]],'asksave',[[23,1]],'keeps',[[5,1],[22,1],[2,1]],'chronology',[[5,2]],'troublesome',[[7,1]],'completely',[[22,2],[14,1],[8,1],[12,2],[6,2]],'gain',[[22,2],[12,2],[2,1]],'reset',[[3,1],[22,6],[18,1],[24,2],[15,5],[23,2],[19,4],[25,2],[11,1],[6,1]],'uncheck',[[5,3],[15,1],[12,4],[11,1]],'cloudlet',[[22,3],[23,1],[16,1],[5,3]],'desired',[[22,7],[24,1],[16,2],[11,1],[5,4]],'muscle',[[16,1]],'visualization',[[7,1],[2,2],[8,1],[12,1],[14,1]],'before',[[6,1],[20,1],[18,4],[22,13],[16,2],[15,3],[17,3],[2,3],[8,2],[9,6],[3,1],[24,3],[4,4],[10,4],[25,2],[5,8],[19,2],[23,1],[14,2],[7,5],[11,7],[12,4]],'normal',[[11,2],[14,1],[22,5],[15,2],[23,1],[7,1],[2,1],[8,2],[12,1],[9,1]],'false',[[22,2],[18,3],[25,1],[23,1]],'innovation',[[22,1]],'change',[[6,3],[22,39],[18,4],[15,4],[17,41],[2,1],[9,5],[3,1],[24,4],[4,7],[10,2],[5,15],[19,2],[23,5],[7,2],[11,4],[12,5]],'flagpole',[[6,1]],'fixes',[[9,1],[12,1]],'200',[[8,1],[11,4],[6,3]],'absence',[[22,1],[20,3]],'unpause',[[4,2],[15,3],[5,3],[17,1],[7,1],[12,3],[9,1]],'timeline',[[5,2],[22,7],[24,1],[15,2],[6,1]],'including',[[19,1],[22,9],[23,2],[14,1],[11,1],[6,1]],'controls',[[22,2],[4,1],[10,2],[15,6],[5,2],[19,1],[0,1],[23,2],[14,1],[13,2],[11,5],[9,1]],'simplify',[[5,1],[20,1],[22,1],[12,1],[6,1]],'hit',[[22,1]],'impulse',[[12,1]],'interacts',[[23,1]],'greenzone',[[22,55],[18,3],[16,1],[15,1],[17,29],[2,1],[9,1],[24,7],[4,7],[10,1],[25,5],[5,10],[19,2],[23,12],[7,1],[14,3],[12,11],[11,22]],'pointing',[[5,1],[22,1],[25,1],[16,2],[15,3],[11,1]],'obeying',[[2,1]],'slash',[[15,1]],'recently',[[3,1],[22,1],[4,2],[11,3]],'cancelled',[[23,1],[15,1],[5,1]],'visual',[[22,2],[4,1],[14,1]],'thoroughly',[[20,1],[10,1],[14,1]],'meditating',[[2,1]],'gave',[[22,1]],'after',[[6,11],[20,2],[18,2],[22,30],[16,4],[15,1],[17,24],[2,2],[8,10],[9,5],[24,4],[4,3],[10,6],[25,6],[5,13],[19,2],[23,5],[14,1],[7,11],[11,11],[12,10]],'predictable',[[14,1],[2,1]],'framenum',[[17,2]],'polishing',[[6,3],[20,1],[10,2],[23,1],[7,2],[14,1],[8,3],[12,1],[9,2]],'having',[[8,1],[20,1],[23,1]],'meet',[[12,1]],'latest',[[4,2],[7,3],[9,1],[6,1]],'lock',[[9,1]],'behaviors',[[23,1]],'huge',[[4,1],[2,1],[12,4],[23,1]],'bookmark5',[[17,1]],'greenzonx',[[25,1]],'extent',[[22,1],[14,1]],'assumes',[[24,1],[15,1]],'wish',[[0,1],[4,1],[1,2],[16,2],[11,1],[5,1]],'surely',[[2,1]],'indicate',[[4,1],[12,1]],'timings',[[23,5]],'opened',[[24,2],[4,1],[12,1]],'delayed',[[14,2],[9,1],[2,1]],'information',[[22,13],[15,2],[2,1],[8,1],[9,2],[3,1],[24,1],[4,1],[10,2],[5,1],[14,3],[7,3],[12,2],[11,2]],'edited',[[12,1],[22,3],[4,2],[10,1],[16,7],[5,5],[23,1],[8,1],[11,4],[9,1]],'satisfied',[[8,1],[20,1],[6,1]],'tiresome',[[8,1],[7,1]],'frequency',[[8,1]],'poll',[[23,1],[11,1],[14,2]],'mid',[[15,3]],'leaving',[[22,2],[10,1],[4,1],[9,1],[11,2]],'changed',[[22,14],[24,2],[4,2],[10,3],[18,4],[16,1],[5,6],[17,20],[23,1],[7,1],[6,1]],'potentially',[[8,1],[10,1]],'pressed',[[22,10],[4,3],[18,3],[16,2],[25,5],[5,1],[12,2],[11,1]],'content',[[8,1],[5,1]],'unfortunately',[[19,1],[6,2]],'major',[[2,1],[16,1],[15,1],[21,1]],'existed',[[11,1],[12,2]],'listing',[[11,1]],'enable',[[12,1],[15,2],[24,3],[8,1],[11,7],[5,1]],'training',[[8,1]],'opinion',[[12,1]],'already',[[12,3],[22,4],[4,6],[10,3],[18,2],[15,2],[23,1],[2,1],[1,1],[7,3],[11,4],[6,4]],'inattention',[[6,1]],'cursor',[[20,3],[22,83],[18,3],[16,43],[15,59],[17,5],[8,6],[9,22],[24,12],[4,30],[10,15],[5,54],[19,4],[23,12],[7,5],[14,9],[12,8],[11,24]],'10001000',[[17,1],[11,1]],'temptation',[[9,1],[6,1]],'inability',[[7,1]],'beforehand',[[7,1],[5,1]],'principles',[[10,1],[5,1],[19,1],[2,1],[7,1],[11,1],[6,1]],'cleaning',[[11,2],[23,3]],'memorable',[[12,1]],'stores',[[3,2],[12,1],[22,11],[24,1],[25,1],[23,38],[14,1],[8,1],[20,1],[9,1]],'experience',[[22,1],[2,2],[8,1],[12,2],[6,1]],'have',[[6,22],[20,4],[18,1],[22,14],[15,2],[2,6],[8,7],[9,4],[3,1],[24,2],[4,6],[10,1],[25,1],[5,6],[19,1],[23,4],[14,7],[7,15],[11,25],[12,8]],'auxiliary',[[8,1],[15,1],[14,1]],'accidental',[[5,1]],'improvement',[[6,6],[22,4],[14,2],[1,1],[8,1],[20,1],[9,1]],'restriction',[[22,1]],'context',[[22,2],[24,2],[4,2],[16,3],[15,4],[23,1],[17,8],[19,5],[2,1],[14,1],[11,3],[6,1]],'fundamental',[[5,1]],'late',[[5,1]],'gather',[[14,1]],'illuminating',[[15,1]],'steps',[[4,1],[10,1],[5,2],[7,1],[8,5],[9,3],[11,1]],'fer',[[24,1]],'atmosphere',[[2,1]],'top',[[22,1],[4,2],[12,1],[5,2]],'hovers',[[22,1]],'required',[[19,1],[20,1],[22,1],[25,8],[12,1],[5,1]],'although',[[6,1],[22,1],[17,1],[7,1],[14,1],[20,1],[12,2]],'forcing',[[5,1]],'specifications',[[19,2],[0,1],[13,1],[21,1],[25,1]],'performed',[[22,1],[14,1]],'features',[[22,3],[18,1],[16,1],[2,3],[3,1],[4,1],[5,1],[19,3],[0,1],[23,3],[14,10],[1,2],[11,3],[12,2]],'advantages',[[12,1],[2,1]],'enter',[[3,1],[9,1],[4,2],[22,1],[16,2],[15,2],[5,1],[17,3],[11,1],[12,1]],'colors',[[22,6],[4,1],[11,1],[23,2]],'seeking',[[22,21],[24,2],[10,3],[18,6],[16,2],[15,6],[5,9],[23,4],[2,1],[14,1],[11,4],[9,4]],'eye',[[14,1],[22,1],[2,1]],'tests',[[10,1],[2,1],[14,1],[6,1]],'scenery',[[10,1]],'incomplete',[[6,1]],'conditions',[[23,1],[14,2],[12,1],[6,2]],'canvas',[[22,3]],'recalculates',[[23,1]],'unmark',[[23,1]],'pale',[[22,2],[24,1],[4,1],[11,4],[5,1]],'detection',[[14,1]],'resizing',[[23,1]],'separator',[[25,4]],'restart',[[12,1]],'definite',[[20,1],[6,1]],'skip',[[5,1],[11,2],[10,1],[15,1],[9,2],[6,1]],'hover',[[5,2],[22,1],[15,4],[11,2]],'subtitles',[[25,1],[12,5],[15,1]],'markers',[[6,5],[22,45],[18,5],[16,7],[15,13],[17,36],[2,1],[9,2],[4,15],[25,5],[5,8],[19,2],[23,25],[14,4],[12,17],[11,17]],'presence',[[22,1],[20,3],[5,1]],'made',[[9,1],[12,1],[18,5],[22,4],[16,1],[5,3],[23,1],[2,1],[7,1],[14,4],[11,1],[6,5]],'dedicated',[[22,3],[0,1],[4,1],[7,1],[11,1],[5,2]],'filtered',[[22,1]],'shall',[[3,1]],'gridview',[[22,1]],'cloning',[[23,1]],'constitute',[[25,1]],'graphically',[[22,1]],'description',[[3,2],[6,2],[4,1],[22,2],[16,3],[15,2],[23,1],[12,2],[11,1]],'suffix',[[12,1]],'10000',[[11,1]],'prolific',[[2,1]],'alive',[[18,2]],'ntsc',[[18,1]],'aims',[[14,1],[2,1]],'expand',[[22,2],[18,3]],'same',[[6,9],[20,6],[22,20],[16,3],[15,6],[17,1],[2,4],[9,2],[24,3],[4,6],[10,3],[25,2],[5,10],[19,1],[23,1],[7,7],[14,1],[11,11],[12,4]],'described',[[3,3],[12,2],[4,1],[22,1],[16,1],[5,3],[7,3],[14,1],[11,1],[6,1]],'piece',[[6,2]],'repeatedly',[[22,1],[7,1]],'engage',[[3,1]],'contradicts',[[6,1]],'offsets',[[25,4],[23,1]],'aspect',[[6,2],[14,2],[2,1]],'results',[[11,1],[12,1],[4,1],[14,3],[20,2],[5,2],[23,1],[2,1],[7,3],[8,2],[9,1],[6,4]],'influence',[[6,2],[10,1],[2,1]],'superplay',[[14,1]],'seldom',[[7,1]],'coordinate',[[14,1],[22,1],[6,8]],'iphone',[[6,1]],'speedrunner',[[6,1]],'tail',[[17,1],[22,1],[11,4]],'year',[[7,1]],'via',[[15,1],[2,1],[12,1],[5,1]],'snapshot',[[19,1],[22,2],[23,17],[14,1],[11,1],[12,2]],'emulation',[[11,2],[22,11],[18,2],[15,2],[2,1],[9,6],[24,1],[4,3],[10,1],[5,8],[23,6],[7,1],[14,6],[12,4],[20,1]],'spawn',[[22,1]],'static',[[22,1]],'specialized',[[22,1]],'repeated',[[7,1],[12,1],[6,1]],'urges',[[10,1]],'obsolete',[[10,1]],'decrease',[[15,1],[11,1],[6,1]],'organized',[[12,1],[6,1]],'desktop',[[3,2],[22,1],[2,1]],'programs',[[4,1],[14,1]],'unlock',[[6,1]],'irritating',[[11,1]],'accurate',[[22,1],[12,1]],'toolset',[[2,1]],'any',[[6,13],[20,3],[22,30],[16,10],[15,8],[17,3],[2,7],[8,4],[9,3],[3,2],[24,3],[4,14],[10,5],[25,3],[5,23],[19,1],[23,8],[14,9],[7,5],[11,7],[12,7]],'explore',[[16,2]],'при',[[22,1]],'conflict',[[24,1]],'uint64',[[25,1]],'limitations',[[11,1],[14,1]],'skill',[[8,2],[12,1],[6,2]],'clicking',[[9,2],[22,18],[4,6],[18,1],[24,1],[15,8],[5,5],[17,3],[19,1],[11,2],[12,1]],'observe',[[4,3],[16,1],[5,1],[2,1],[14,1],[8,1],[11,1]],'drop',[[22,2],[7,1],[11,1],[9,1]],'consists',[[20,1],[22,1],[25,5],[14,4],[12,2],[5,1]],'extreme',[[22,1],[6,1]],'persistence',[[7,1]],'hits',[[9,1]],'appeared',[[22,1],[11,3],[2,1]],'chose',[[11,2],[23,1]],'submitted',[[18,1]],'classification',[[13,1]],'unnecessary',[[14,1]],'syncing',[[14,1]],'contained',[[22,4],[4,1],[12,1]],'who',[[2,1],[1,2],[7,1],[6,3]],'illogical',[[8,1],[10,1]],'periodically',[[22,1],[18,1]],'drawing',[[12,4],[22,3],[4,2],[10,1],[15,2],[5,1],[23,1],[0,1],[14,1],[11,4],[9,1]],'capturing',[[22,1]],'describes',[[3,1],[12,1],[1,1],[21,1],[11,3],[6,1]],'many',[[6,15],[22,9],[16,2],[15,1],[2,5],[8,4],[3,1],[24,1],[4,2],[10,3],[5,3],[14,7],[12,8],[11,4]],'replace',[[24,1],[18,2],[11,1],[12,1]],'positioned',[[22,1]],'annoyed',[[11,2]],'narrow',[[22,1],[24,1],[4,1]],'initialized',[[22,1]],'adjustlag',[[22,5]],'notepad',[[3,1],[22,1],[2,1],[12,1]],'separated',[[6,2]],'planned',[[22,2],[6,1]],'changing',[[22,7],[24,1],[4,1],[10,1],[15,1],[5,1],[23,5],[2,1],[14,1],[12,1],[11,1]],'books',[[17,1],[6,1]],'intermediaries',[[10,1]],'urgently',[[6,1]],'size',[[22,7],[11,3],[6,2],[16,1],[3,3],[4,1],[25,5],[5,3],[23,5],[7,1],[14,1],[12,13],[20,1]],'configured',[[22,2],[11,1]],'digit',[[22,5],[4,1]],'checked',[[22,3],[18,4],[16,1],[15,1],[5,2],[23,1],[12,3]],'places',[[22,2],[15,1],[23,1],[17,1],[19,1],[7,1],[12,5]],'savestate',[[22,12],[24,11],[15,12],[5,2],[23,7],[7,21],[14,3],[12,4],[11,5]],'repaid',[[12,1]],'valid',[[25,1]],'savestates',[[14,1],[22,10],[24,5],[25,1],[5,3],[23,9],[2,1],[7,5],[8,5],[11,2],[6,2]],'distance',[[5,2],[22,2],[7,1],[6,1]],'previously',[[22,3],[4,1],[18,5],[16,2],[11,2],[20,1]],'coin',[[24,2],[15,3]],'theme',[[4,1]],'achieve',[[7,1],[6,1]],'hardly',[[22,1]],'fly',[[10,1],[2,1],[12,2],[5,1]],'less',[[12,4],[22,1],[4,1],[10,3],[18,2],[24,2],[23,2],[2,2],[7,3],[8,2],[11,1],[6,6]],'specify',[[11,1]],'intelligence',[[14,1]],'disappear',[[17,4],[22,3],[4,1],[10,1],[12,1]],'sounds',[[7,1],[22,1],[6,1]],'call',[[22,1],[18,11],[4,2],[12,1],[23,3]],'hexified',[[25,1]],'unimplemented',[[6,1]],'notion',[[23,1],[2,1]],'had',[[4,1],[2,2],[11,1],[12,1]],'spread',[[4,1]],'throw',[[6,2]],'raise',[[2,1]],'work',[[6,8],[22,6],[21,1],[15,6],[2,3],[8,2],[3,1],[24,5],[4,2],[10,1],[5,2],[23,2],[14,1],[7,3],[12,8],[11,12]],'bot',[[14,1]],'collecting',[[22,1],[11,1]],'function',[[22,5],[24,1],[18,26],[15,1],[5,1],[17,5],[23,15],[12,14],[11,7]],'related',[[5,3],[23,1],[24,1],[12,3],[11,1]],'than',[[6,13],[20,6],[18,1],[22,9],[2,9],[8,1],[9,2],[4,1],[10,2],[25,1],[23,3],[19,1],[14,2],[7,4],[11,3],[12,1]],'switches',[[23,1],[11,1],[7,2]],'environment',[[22,1],[0,1],[10,1],[11,1],[12,1]],'tases',[[14,2],[5,1],[2,1],[7,1],[8,1],[11,1],[6,2]],'playthroughs',[[6,1],[5,2]],'autopause',[[22,1],[11,2]],'keep',[[22,2],[6,5],[18,2],[2,2],[9,1],[3,1],[24,1],[4,1],[5,1],[19,1],[7,3],[12,4],[20,4]],'stand',[[4,1]],'attempts',[[6,1]],'collects',[[14,1]],'enforces',[[22,1]],' easier',[[22,1]],'filters',[[23,1]],'boundaries',[[8,1],[6,3]],'back',[[22,8],[24,2],[4,3],[16,1],[15,1],[5,11],[23,1],[25,1],[2,2],[7,4],[8,1],[9,1]],'equals',[[6,1]],'animating',[[23,2]],'programming',[[0,1],[2,2],[14,2],[21,1],[12,2],[20,3]],'cover',[[16,1]],'comprehensive',[[19,1],[0,1],[14,1]],'monotonous',[[6,2],[5,1]],'branch7',[[17,2]],'introduces',[[16,1]],'outside',[[6,1],[22,4],[4,2],[18,7],[24,1],[16,1],[15,7],[5,1],[17,3],[12,1],[9,2]],'frames',[[6,9],[22,43],[18,6],[16,7],[15,23],[17,41],[2,2],[8,1],[9,3],[24,4],[4,25],[25,1],[5,27],[19,1],[23,8],[14,8],[7,4],[11,38],[12,11]],'trailing',[[9,1]],'slowdown',[[2,2]],'distribute',[[8,1]],'3100',[[11,1]],'fed',[[4,1]],'speedrunning',[[0,1],[7,1],[2,1],[13,1],[20,2]],'commonplace',[[12,1]],'dependence',[[6,2]],'300',[[11,1],[6,1]],'unnoticeable',[[14,1],[7,1]],'yellow',[[22,7],[4,2],[14,1],[11,2]],'precision',[[14,1],[8,1],[11,1],[15,1]],'hitting',[[5,1]],'command',[[15,9],[19,2],[22,1],[7,2],[12,1],[5,1]],'valuable',[[2,1]],'invoke',[[15,6],[23,1]],'whole',[[22,3],[11,3],[6,5],[15,1],[2,2],[8,2],[24,1],[5,2],[0,1],[14,1],[7,3],[12,4],[20,2]],'experienced',[[6,2],[2,2],[1,1],[7,4],[5,1]],'pop',[[22,11],[11,7],[5,1]],'doesn',[[11,4],[20,1],[18,3],[22,2],[16,1],[15,2],[8,1],[9,1],[24,7],[10,2],[25,2],[23,3],[19,2],[7,1],[14,2],[12,2],[6,3]],'drag_mode_deselection',[[24,1]],'never',[[17,1],[8,1],[9,2],[11,1]],'icon',[[22,7],[24,3],[16,1],[15,5],[23,1],[17,3],[20,1],[9,1]],'providing',[[14,1]],'power',[[19,1],[23,1],[24,2],[25,2],[15,4],[5,1]],'him',[[6,1],[2,3]],'hard',[[6,1],[22,1],[5,1],[7,1],[8,1],[12,1],[11,1]],'isolate',[[6,1],[2,1]],'beaten',[[12,1],[14,1]],'fm2',[[17,2],[24,9],[14,1],[2,3],[12,12],[25,8]],'rule',[[12,1],[6,1]],'disadvantages',[[7,1]],'suggest',[[23,1],[24,1],[6,1]],'generic',[[20,1]],'customization',[[22,4],[15,1],[0,1],[14,2],[1,1],[20,1],[11,3]],'tiny',[[3,1]],'caching',[[22,1]],'over',[[6,12],[22,10],[15,12],[2,2],[8,1],[9,1],[24,5],[4,1],[10,3],[5,3],[19,1],[23,1],[7,1],[11,6],[12,6]],'serves',[[22,5],[4,1],[14,1],[9,2],[15,1]],'slipped',[[6,1]],'good',[[20,1],[23,1],[10,1],[2,2],[9,1],[12,1]],'happening',[[22,1],[8,1]],'triggered',[[22,1],[18,1]],'timed',[[6,1]],'accentuate',[[6,1]],'dragging',[[3,1],[22,6],[4,3],[24,1],[16,3],[15,1],[5,1],[17,3],[19,1],[11,1],[9,1]],'receives',[[11,1],[12,1]],'entirely',[[22,1]],'magnifying',[[22,1]],'inevitable',[[6,1]],'experiments',[[4,1],[7,4],[14,1],[6,1]],'fill',[[22,1],[16,1],[12,1],[5,1]],'resort',[[7,1]],'return',[[22,2],[18,3],[16,4],[15,1],[2,1],[8,4],[9,2],[4,1],[10,2],[5,4],[7,4],[12,2],[11,3]],'site',[[23,1],[25,1],[2,1]],'obstacle',[[9,1]],'highlights',[[14,1],[4,1],[11,1]],'stress',[[5,1],[2,1]],'looks',[[12,1]],'rolls',[[14,1]],'begin',[[22,1],[4,2],[10,2],[15,1],[7,1],[12,1],[6,2]],'stages',[[22,1],[6,1]],'Все',[[22,1]],'yet',[[24,1],[4,1],[10,1],[18,1],[17,3],[19,1],[7,3],[2,1],[8,3],[11,1],[12,1]],'terminated',[[25,1]],'key',[[6,2],[22,7],[16,4],[15,7],[17,6],[2,3],[8,1],[9,2],[3,1],[24,1],[4,9],[10,1],[25,4],[5,8],[23,3],[7,2],[11,9],[12,2]],'source',[[21,5],[17,2],[19,2],[7,2],[14,2],[12,2],[9,1]],'continue',[[5,1],[12,1],[19,1],[7,3],[9,3],[6,1]],'taseditor_patterns',[[24,1],[12,1]],'genius',[[7,1]],'sweeping',[[11,1]],'likely',[[12,3],[22,1],[4,1],[10,1],[16,1],[2,1],[7,1],[11,2],[6,1]],'stopped',[[9,1],[18,2]],'smallest',[[5,1]],'realm',[[2,1]],'long',[[12,3],[22,8],[4,1],[10,1],[15,3],[5,2],[19,1],[2,2],[7,3],[11,5],[6,4]],'assess',[[6,1]],'right',[[6,9],[22,21],[18,3],[16,1],[15,16],[17,13],[8,5],[9,4],[3,3],[24,4],[4,8],[10,2],[25,5],[5,12],[19,8],[23,2],[7,3],[14,1],[11,5],[12,6]],'distracted',[[6,1]],'mobile',[[6,1]],'people',[[12,2],[2,2],[1,1],[7,3],[8,2],[6,4]],'standard',[[3,1],[24,2],[4,2],[15,1],[5,1],[2,1],[7,1],[11,2],[12,3]],'feeling',[[4,1]],'examination',[[10,1],[7,1]],'facepalms',[[6,1]],'fullscreen',[[24,1]],'complete',[[10,1],[9,1],[7,4]],'microphone',[[14,1]],'official',[[21,1],[25,1]],'succession',[[6,1],[12,1],[2,1]],'receiving',[[2,1]],'erroneously',[[7,1]],'truncates',[[22,1],[23,2],[10,1],[5,1]],'accidentally',[[24,3],[9,1],[5,1]],'meta',[[6,1]],'invented',[[22,1],[4,1],[2,2]],'invoking',[[15,1]],'released',[[22,5],[24,1],[4,2],[16,1],[12,2],[5,1]],'pile',[[18,1]],'walk',[[6,1]],'browse',[[12,1]],'megabytes',[[11,1],[12,2]],'helper',[[12,1]],'easy',[[12,1],[20,1],[4,1],[25,1],[5,3],[7,1],[1,1],[14,3],[11,2],[6,3]],'development',[[22,1],[0,1],[10,1],[2,3],[6,1]],'losing',[[14,1],[8,1],[6,2]],'especially',[[15,1],[20,1],[14,1],[11,1],[6,3]],'oftentimes',[[12,1]],'unconsciously',[[6,1]],'allot',[[9,1]],'off',[[22,6],[18,1],[8,2],[9,2],[3,1],[24,2],[4,1],[10,2],[25,1],[5,2],[19,3],[23,1],[7,1],[11,4],[6,2]],'regularly',[[22,1],[11,1],[23,15]],'truncate',[[22,4],[15,1],[5,1],[17,5],[19,1],[8,1],[11,1]],'popularity',[[22,1]],'which',[[6,13],[20,4],[18,2],[22,16],[16,5],[21,1],[17,2],[8,2],[9,3],[4,4],[10,1],[25,13],[5,1],[19,2],[23,4],[7,1],[14,4],[11,9],[12,8]],'construction',[[2,1]],'progressing',[[8,1]],'avi',[[15,2],[14,1]],'similar',[[22,7],[16,4],[15,1],[2,1],[8,2],[9,1],[3,1],[4,2],[10,1],[5,5],[19,1],[23,2],[14,1],[12,11],[6,3]],'satisfactory',[[7,1]],'totally',[[23,1],[24,1],[4,1],[2,1],[5,1]],'scrollbars',[[15,2]],'portrayed',[[6,1]],'relation',[[22,2],[2,1]],'web',[[1,1],[8,1],[6,1]],'controllers',[[11,1]],'unavailable',[[24,1]],'physically',[[2,1]],'published',[[12,1],[6,1]],'panel',[[2,1],[16,3],[12,1],[23,2]],'preferred',[[4,1],[5,2]],'sufficient',[[8,2],[7,1]],'repeats',[[7,1]],'contexts',[[7,1]],'inaccessible',[[11,1]],'enabling',[[11,1]],'recollect',[[16,1]],'container',[[14,2]],'port',[[19,1],[24,1],[25,3]],'alternatively',[[20,1],[15,1],[5,1]],'bringing',[[20,1],[10,1],[12,1]],'1000',[[5,1],[22,3],[23,1],[8,2],[11,2],[6,4]],'following',[[22,7],[18,1],[15,2],[17,4],[2,2],[3,1],[24,4],[4,2],[25,7],[5,1],[19,1],[23,2],[14,1],[11,2],[6,3]],'entertaining',[[7,1]],'developed',[[22,1],[2,1]],'readbyte',[[12,3]],'far',[[9,2],[12,1],[4,1],[22,2],[16,1],[5,1],[2,1],[11,2],[6,1]],'generate',[[13,1],[4,1]],'mit',[[21,1]],'frequent',[[12,1]],'countdown',[[14,1]],'rewatch',[[7,2],[9,1],[6,1]],'optional',[[10,2],[8,2],[9,2],[25,7]],'anymore',[[22,1],[2,1]],'skidding',[[6,1]],'mechanisms',[[7,1]],'unsetting',[[15,2]],'split',[[11,2]],'evens',[[4,1]],'reading',[[11,1],[6,1],[23,6],[19,1],[7,1],[12,1],[20,1]],'stable',[[23,1],[8,1],[6,1]],'sweat',[[6,2]],'initializes',[[12,1]],'bookmark3',[[17,1]],'superstructure',[[24,1]],'occur',[[6,4],[12,1],[20,1],[11,1],[9,2]],'updated',[[22,4],[9,1]],'emerged',[[6,1]],'problem',[[19,1],[20,2],[22,1],[9,1],[12,2]],'significant',[[22,1]],'shown',[[22,6],[18,1],[4,1],[11,1]],'left',[[6,2],[22,32],[18,2],[16,1],[15,16],[2,1],[8,3],[3,1],[24,3],[4,14],[25,3],[5,11],[7,1],[12,8],[11,5]],'thereby',[[11,1]],'just',[[6,10],[20,2],[22,5],[2,8],[9,4],[3,1],[24,1],[4,13],[10,3],[25,1],[5,7],[19,1],[23,1],[7,9],[14,1],[11,8],[12,4]],'seeks',[[10,1]],'opportunity',[[14,1]],'falls',[[10,1]],'impractical',[[9,1],[11,2]],'contents',[[3,2],[22,11],[4,1],[24,1],[5,4],[17,1],[23,2],[8,2],[11,2],[20,1]],'manipulation',[[10,1],[14,3],[9,1],[20,1]],'port0',[[24,1],[25,7]],'paragraphs',[[6,1]],'newtext',[[17,1],[18,2]],'unbound',[[20,1]],'selected_frame',[[12,3]],'perceive',[[12,1],[2,1],[11,1],[6,1]],'publishing',[[6,1],[2,1]],'optimal',[[20,2],[10,1],[7,2],[14,2],[12,1],[6,2]],'comparisons',[[7,1]],'practically',[[9,1],[10,1]],'role',[[7,1],[15,1],[2,1]],'movement',[[7,1],[23,3],[5,2]],'revert',[[16,2],[5,1],[17,1],[23,1],[7,1],[11,2],[9,1]],'formatting',[[12,1]],'caller',[[23,7]],'different',[[6,3],[22,9],[16,1],[15,2],[17,1],[2,1],[8,5],[9,3],[24,1],[4,3],[10,4],[5,4],[14,4],[7,2],[11,4],[12,5]],'competent',[[1,1]],'inserts',[[17,2],[5,3]],'ending',[[17,1],[22,1],[25,1],[14,2],[9,2],[6,1]],'say',[[22,1],[11,1],[7,1]],'entails',[[7,1]],'later',[[3,2],[22,1],[4,2],[24,1],[9,5],[5,4]],'perfunctory',[[9,1]],'touching',[[14,1],[7,1]],'remains',[[22,3],[12,1],[5,1]],'buttons',[[6,2],[22,21],[18,7],[15,3],[17,4],[2,2],[8,2],[9,1],[4,5],[25,3],[5,19],[19,1],[23,9],[14,1],[11,12],[12,4]],'record',[[11,7],[22,7],[24,2],[15,2],[5,6],[17,44],[25,12],[2,1],[14,2],[8,1],[12,6],[6,3]],'encompasses',[[7,1]],'consecutively',[[22,1]],'someone',[[8,1],[2,1]],'glass',[[22,1]],'will',[[6,9],[20,2],[18,41],[22,59],[16,1],[15,31],[2,3],[8,5],[9,6],[3,4],[24,12],[4,30],[10,10],[25,4],[5,33],[19,3],[23,2],[7,4],[1,1],[14,3],[11,54],[12,40]],'object',[[22,1],[14,2],[2,1],[15,1]],'symbol',[[22,3],[4,1],[15,5],[17,3],[14,1],[12,1],[11,4]],'your',[[6,14],[20,1],[18,5],[22,2],[16,1],[15,1],[2,4],[8,3],[9,7],[3,1],[24,1],[4,7],[10,7],[5,14],[14,2],[7,10],[11,12],[12,15]],'carried',[[6,2],[10,1],[2,1]],'resizable',[[22,1]],'10th',[[4,1]],'gradually',[[11,1],[4,1],[7,1],[9,1],[6,1]],'dislocated',[[5,1]],'pads',[[17,1],[23,4],[5,2]],'0000020',[[4,1]],'six',[[25,1]],'motivates',[[7,1],[6,1]],'adjustment',[[8,1],[11,3],[12,1]],'lots',[[11,1],[2,1]],'modifying',[[22,1],[23,1],[7,1],[14,1],[9,3],[6,1]],'world',[[6,8],[10,3],[2,4],[14,1],[12,3],[5,1]],'forgetting',[[11,1],[5,1]],'setmarker',[[17,2],[18,2]],'sharing',[[22,1],[12,1]],'hanging',[[22,1]],'harmful',[[2,1]],'leads',[[14,1],[4,1],[7,1]],'pit',[[5,1],[10,2],[8,1],[12,1],[6,4]],'shifted',[[17,2],[22,3],[11,1],[5,1]],'advisable',[[3,1]],'theory',[[22,1],[24,1],[11,1],[6,1]],'bit3',[[25,2]],'inherent',[[9,1],[5,1]],'forward',[[22,1],[10,1],[16,1],[15,1],[5,7],[25,1],[7,1],[14,2],[9,1],[6,2]],'these',[[6,7],[20,1],[18,3],[22,8],[15,4],[2,2],[8,3],[24,2],[4,5],[10,1],[5,10],[0,1],[14,1],[7,4],[12,2],[11,4]],'ill',[[6,1]],'wip',[[6,1]],'constantly',[[22,1],[24,1],[10,1],[23,1],[7,1],[2,1],[9,1],[6,1]],'jump',[[22,7],[6,3],[15,3],[2,1],[9,1],[24,2],[4,5],[10,2],[5,25],[23,3],[7,1],[14,1],[11,2],[12,4]],'things',[[2,2],[14,1],[8,1],[6,3]],'running',[[6,1],[22,1],[4,2],[18,2],[24,1],[15,1],[5,2],[14,1],[12,2],[11,2]],'intellectual',[[6,1]],'upcoming',[[14,1],[9,1],[10,1]],'been',[[22,1],[11,2]],'heavy',[[11,1]],'thousands',[[16,2]],'cached',[[22,1]],'upon',[[7,1],[8,1],[6,1]],'sight',[[19,1],[9,1]],'getrecordermode',[[18,2]],'elements',[[5,2],[22,1],[24,3],[15,1],[11,2]],'vast',[[11,1],[6,1]],'around',[[22,1],[11,1]],'recalculating',[[23,1]],'wait',[[5,2],[20,1],[22,1],[11,3],[6,1]],'place',[[6,4],[20,1],[22,9],[16,3],[15,3],[17,1],[2,3],[8,2],[24,1],[4,2],[10,1],[5,7],[19,1],[7,8],[12,1],[11,3]],'pipe',[[25,3],[6,2]],'rldutsba',[[25,1]],'picked',[[15,1]],'core',[[23,1]],'ends',[[22,2],[6,3],[4,1],[25,1],[14,1],[12,2],[9,1]],'values',[[22,11],[12,3],[25,5],[23,2],[14,2],[20,1],[11,1]],'space',[[3,1],[22,2],[6,1],[25,4],[5,1],[23,2],[12,1],[11,4]],'disassembly',[[14,1]],'correlate',[[22,1],[4,1],[12,1]],'everyframe',[[12,4]],'approach',[[20,34],[6,13],[22,1],[15,1],[2,2],[8,10],[9,9],[10,6],[5,1],[14,1],[7,8],[11,5],[12,4]],'capture',[[11,2]],'mechanism',[[1,1],[7,1]],'objective',[[6,2],[8,1],[2,1]],'gateway',[[22,5]],'personal',[[22,1],[11,1],[18,1],[6,1],[15,1],[2,1],[8,1],[9,1],[3,1],[25,1],[7,1],[1,1],[13,1],[16,1],[21,1],[17,1],[24,1],[4,1],[10,1],[5,1],[19,1],[0,1],[23,1],[14,1],[12,1],[20,1]],'frontier',[[6,1]],'judge',[[9,1],[20,2]],'focusing',[[22,1]],'envelope',[[22,1]],'performs',[[22,1]],'shifting',[[5,2],[17,4],[11,3],[6,1]],'rewritten',[[23,1],[6,1]],'precious',[[10,1]],'thumb',[[16,1]],'stack',[[22,2],[23,2]],'turned',[[25,1]],'solutions',[[12,1],[14,1]],'booleans',[[20,2],[25,1]],'ordinary',[[14,2]],'layout',[[22,1]],'regular',[[11,3],[22,1],[24,2],[5,2],[23,1],[2,2],[7,3],[12,2],[6,5]],'critically',[[6,1]],'finally',[[3,1],[20,1],[22,1],[11,4],[5,1]],'uses',[[3,1],[12,1],[22,3],[25,2],[11,1],[6,1]],'rebuilt',[[5,1]],'executes',[[22,1]],'1010',[[17,1],[11,1],[5,1]],'hours',[[11,1]],'fourth',[[22,1]],'divided',[[3,1],[22,1]],'consume',[[9,1]],'improve',[[6,2],[12,1],[4,1],[20,1],[22,2],[24,1],[2,1],[1,1],[14,1],[11,1],[9,1]],'greatly',[[14,1],[23,1],[5,2]],'purposely',[[12,1]],'resumes',[[24,1],[5,1]],'sub',[[3,1]],'disables',[[24,1]],'pending',[[18,1],[23,1]],'direct',[[3,1],[6,1],[2,2],[7,1],[14,1],[5,1]],'item',[[3,6],[9,7],[18,1],[22,32],[15,1],[5,8],[23,2],[11,8],[12,1]],'supermariobros',[[12,1]],'quantity',[[14,1]],'examine',[[9,1],[7,1]],'days',[[4,1],[6,1]],'involvement',[[7,1]],'strategy',[[11,1],[5,1]],'counted',[[25,1]],'internal',[[25,4],[6,1]],'teleport',[[7,1]],'reads',[[23,1],[6,1]],'refuse',[[6,1],[24,1],[14,1],[23,1]],'insignificantly',[[12,4]],'implement',[[22,4],[23,1],[5,2]],'mnemonics',[[25,1],[23,1]],'making',[[11,2],[12,4],[10,2],[14,5],[18,2],[22,2],[23,4],[7,7],[2,1],[8,1],[9,1],[6,4]],'palflag',[[25,1]],'search',[[3,1],[6,1],[10,1],[20,5],[22,12],[16,2],[15,1],[2,1],[14,2],[12,8],[9,1]],'pros',[[10,1],[7,1],[14,2],[8,1],[9,1],[11,1]],'through',[[3,1],[11,3],[4,1],[12,3],[20,2],[16,2],[22,10],[5,2],[7,3],[9,1],[6,3]],'maximize',[[6,2]],'dash',[[19,1],[22,1],[4,1],[11,2]],'unchecked',[[18,1],[5,1]],'seems',[[6,1]],'déformation',[[2,1]],'markerx',[[25,1]],'incompatible',[[24,1]],'inevitably',[[6,1]],'end',[[6,23],[20,2],[18,2],[22,8],[16,14],[15,8],[17,3],[2,1],[8,2],[9,11],[3,1],[24,2],[4,1],[10,10],[25,2],[5,6],[19,1],[23,5],[14,1],[7,2],[11,5],[12,11]],'series',[[22,1],[10,1]],'corner',[[6,1],[4,2],[2,1],[12,1],[5,1]],'taken',[[22,5],[11,1]],'shadow',[[5,1]],'stylus',[[14,1]],'port1',[[24,1],[25,7]],'inbuilt',[[2,1]],'starts',[[22,9],[4,3],[10,3],[18,1],[15,2],[5,3],[23,2],[25,3],[12,1],[6,1]],'and',[[22,182],[11,74],[18,14],[6,119],[15,40],[2,45],[8,33],[9,51],[3,13],[25,25],[7,55],[1,5],[13,1],[16,16],[21,5],[17,58],[24,26],[4,53],[10,44],[5,88],[19,13],[0,2],[23,91],[14,40],[12,94],[20,25]],'find',[[6,5],[20,2],[18,1],[22,5],[16,9],[15,3],[17,1],[8,2],[9,1],[3,1],[4,1],[10,1],[5,2],[23,1],[7,3],[14,2],[11,3],[12,5]],'estimated',[[6,1],[10,1],[5,1]],'next',[[6,7],[20,2],[22,6],[16,8],[15,3],[2,2],[8,3],[9,4],[3,1],[24,1],[4,2],[10,2],[25,2],[5,7],[19,1],[14,1],[7,3],[11,5],[12,1]],'user',[[22,41],[24,26],[18,9],[15,1],[5,1],[23,11],[7,1],[2,1],[14,1],[11,2]],'laying',[[9,1]],'color',[[22,18],[4,8],[15,2],[5,1],[14,3],[12,1],[11,6]],'plenty',[[12,1],[2,1]],'friendly',[[14,1]],'opening',[[3,1],[24,2],[23,2]],'creating',[[20,3],[22,5],[15,1],[17,2],[2,2],[8,2],[3,1],[24,1],[4,1],[5,1],[19,1],[23,10],[14,3],[7,3],[11,1],[12,2]],'thoughtful',[[7,1]],'old',[[6,5],[20,18],[18,4],[22,14],[17,8],[2,4],[8,10],[9,4],[24,2],[4,2],[10,2],[5,6],[19,3],[14,2],[7,7],[11,8],[12,1]],'interconnections',[[6,1]],'bar',[[22,1],[8,1],[12,1],[5,5]],'rightclick',[[24,3]],'test',[[11,2],[20,1],[10,3],[5,2],[2,2],[14,1],[8,2],[9,1],[6,3]],'videogames',[[10,1],[0,1],[7,1],[14,3],[8,1],[12,1],[6,1]],'getlostplayback',[[18,2]],'project',[[6,2],[22,26],[21,1],[15,3],[17,3],[2,4],[9,1],[3,3],[24,33],[4,2],[25,4],[5,5],[19,5],[23,25],[7,1],[14,3],[11,15],[12,24]],'carry',[[6,1]],'known',[[22,1],[10,2],[19,1],[2,1],[14,1],[8,1],[9,1]],'properties',[[22,1],[23,3],[20,4],[6,1]],'tab',[[15,2]],'perception',[[2,1]],'remapping',[[11,1]],'becoming',[[4,2]],'fight',[[12,1]],'tricks',[[14,3],[6,2]],'cause',[[22,1],[2,1],[9,1],[5,1]],'effect',[[22,1],[4,1],[2,2],[6,1]],'middle',[[6,2],[12,1],[4,3],[22,3],[24,4],[15,7],[5,3],[23,3],[8,2],[11,5],[9,9]],'robot',[[12,2],[14,1]],'react',[[10,1]],'symbols',[[17,2],[22,6],[4,5],[25,2],[15,2],[11,2]],'attached',[[22,3],[11,2],[25,5]],'subdividing',[[12,1]],'setplayback',[[18,2]],'si_zapper',[[25,4]],'confident',[[6,2]],'develops',[[10,1]],'timer',[[3,1],[14,1],[6,1]],'note',[[6,2],[22,11],[18,3],[16,7],[15,13],[17,9],[3,1],[4,8],[5,1],[19,1],[23,4],[14,3],[11,9],[12,9]],'replayed',[[9,1],[11,1]],'assumed',[[20,1]],'expect',[[6,1]],'carefully',[[16,2],[12,1],[5,1]],'prototype',[[22,2]],'ground',[[7,1],[9,1],[6,2]],'games',[[12,4],[22,1],[10,4],[5,3],[2,1],[7,1],[14,4],[11,4],[6,6]],'ppu',[[24,3],[15,1],[25,1]],'balance',[[20,1],[6,1]],'emphasizing',[[2,1]],'proceed',[[3,1],[20,1],[4,1],[10,1],[2,1],[8,2],[9,1],[6,1]],'saves',[[22,3],[23,12],[25,3],[14,1],[11,1],[5,2]],'casual',[[8,1],[6,1]],'checkboxes',[[10,2],[15,1],[5,3],[19,1],[23,2],[11,2],[9,1]],'relatively',[[22,1]],'inserted',[[17,5],[22,1],[15,1]],'selectbetweenmarkers',[[24,1]],'excitement',[[6,1]],'distinctness',[[14,1]],'simplest',[[20,1]],'distinguishes',[[8,1]],'get',[[6,5],[22,3],[18,5],[16,1],[2,5],[8,4],[9,1],[4,2],[10,2],[5,1],[23,1],[14,1],[11,1],[12,4]],'guaranteed',[[22,1]],'target',[[20,9],[22,6],[18,1],[6,3],[8,4],[9,6],[10,2],[5,9],[19,2],[23,3],[7,1],[11,1],[12,1]],'somewhat',[[9,2],[6,1]],'reload',[[24,1],[11,4],[15,4]],'belong',[[15,1]],'corresponds',[[22,8],[18,1],[14,1],[25,1],[5,1]],'familiar',[[7,1],[5,3]],'every',[[6,11],[20,6],[18,2],[22,14],[15,1],[17,1],[2,2],[8,2],[9,3],[4,4],[10,5],[25,4],[5,9],[23,5],[14,7],[7,2],[11,15],[12,9]],'marked',[[22,5],[4,4],[18,4],[16,2],[5,2],[17,6],[19,1],[14,1],[8,1],[12,4],[11,1]],'emulate',[[22,3],[15,1],[5,1]],'anticipation',[[6,1]],'readonly',[[18,1]],'preset',[[15,3]],'aside',[[5,1]],'reviewed',[[3,1]],'shortcut',[[6,1]],'confinement',[[15,1]],'intersects',[[6,1]],'truncated',[[5,2],[17,30],[18,1],[22,9],[12,1],[11,2]],'progress',[[5,5],[7,2],[8,1],[6,3]],'aforementioned',[[9,1],[11,1]],'design',[[6,1]],'prompt',[[19,1]],'drops',[[9,1]],'workarounds',[[2,1]],'independence',[[7,1]],'dynamic',[[22,1]],'according',[[6,1],[22,2],[10,1],[23,4],[19,1],[7,1],[8,1],[12,3],[11,2]],'comment',[[25,3],[7,5]],'considerable',[[3,1],[11,1],[6,2]],'ingenious',[[6,1]],'experimentally',[[7,1]],'feel',[[12,1],[10,1],[5,1],[19,1],[2,1],[7,1],[9,1],[6,4]],'dream',[[22,1],[2,1]],'stops',[[22,3],[24,1],[18,1],[7,1],[12,1],[11,1]],'slowly',[[15,1]],'parent',[[22,7]],'automation',[[22,2],[14,1]],'thus',[[6,8],[20,3],[22,10],[15,1],[2,5],[8,1],[9,1],[24,1],[4,5],[10,2],[5,5],[19,1],[23,1],[14,4],[7,3],[11,8],[12,1]],'updates',[[18,1],[23,18]],'illusions',[[2,1]],'identical',[[17,2]],'together',[[5,2],[22,3],[7,1],[11,2],[6,1]],'deliver',[[8,1]],'enrich',[[7,1]],'recommended',[[6,1],[20,6],[18,1],[22,1],[16,1],[15,3],[8,2],[9,5],[3,1],[24,2],[4,2],[10,3],[5,3],[19,4],[23,1],[7,1],[14,2],[11,20],[12,9]],'indication',[[22,1]],'contrary',[[6,2]],'essentially',[[4,1],[9,1]],'reader',[[6,1]],'surpass',[[7,1]],'help',[[6,2],[20,2],[18,1],[22,1],[16,1],[21,1],[2,2],[8,1],[9,1],[3,3],[10,2],[25,1],[5,2],[19,2],[23,1],[7,1],[1,2],[11,4],[12,3]],'besides',[[3,2],[12,1],[4,2],[10,1],[22,2],[24,1],[5,3],[19,1],[2,1],[11,1],[6,1]],'rationally',[[5,1]],'gains',[[22,1],[23,1],[7,1]],'graphics',[[10,1],[12,1]],'structures',[[2,1]],'decompressed',[[22,1]],'positions',[[16,1]],'bit5',[[25,2]],'fps',[[15,1],[18,1]],'thing',[[14,1],[12,1],[2,1]],'sections',[[4,1],[2,1],[11,2],[5,1]],'therefore',[[5,1],[22,3],[24,1],[14,1],[12,1],[6,1]],'выходе',[[22,1]],'tags',[[22,1],[12,1]],'frame',[[6,21],[20,17],[18,50],[22,161],[16,29],[15,36],[17,47],[2,12],[8,11],[9,19],[24,5],[4,37],[10,18],[25,5],[5,60],[19,8],[23,24],[14,19],[7,15],[11,36],[12,20]],'loaded',[[17,2],[22,6],[24,4],[25,1],[11,2],[20,1]],'covered',[[3,1],[22,1],[5,1]],'header',[[22,12],[4,3],[15,5],[5,2],[17,8],[23,6],[25,6],[12,1],[11,3]],'comparison',[[22,1],[20,1]],'purposes',[[24,1],[12,1]],'hold',[[12,7],[22,10],[4,6],[10,1],[24,1],[16,5],[15,20],[5,11],[17,1],[2,2],[11,1],[6,4]],'inflict',[[12,1]],'periods',[[6,1]],'gamer',[[6,1],[8,1],[2,2]],'reconsider',[[6,1]],'repeatable',[[12,1]],'manage',[[8,1]],'vary',[[14,1],[7,1]],'fortification',[[12,1]],'comes',[[5,1],[22,1],[18,1],[8,1],[6,4]],'base',[[7,1],[14,1],[8,1],[12,1],[6,1]],'times',[[12,4],[14,1],[18,3],[22,2],[5,2],[23,2],[2,1],[7,1],[8,2],[11,1],[6,3]],'shape',[[2,1]],'bit4',[[25,2]],'brief',[[4,1],[11,1]],'associated',[[22,6],[14,1],[9,1],[25,1]],'config',[[3,1],[22,2],[24,5],[15,1],[5,1],[19,5],[23,4],[11,21]],'constant',[[22,1],[10,1],[2,1],[8,2],[9,1],[6,2]],'diving',[[6,4]],'deliberation',[[22,1]],'possess',[[6,1]],'tooltips',[[3,1],[11,3],[23,1]],'unknown',[[7,2],[22,1],[5,1]],'modern',[[8,1]],'expects',[[24,1],[25,1]],'dialog',[[15,1],[24,6],[11,4],[23,1]],'truncations',[[22,1]],'when',[[6,40],[20,8],[18,10],[22,103],[16,63],[15,19],[17,38],[2,12],[8,12],[9,15],[3,2],[24,32],[4,13],[10,17],[25,9],[5,26],[19,3],[0,2],[23,15],[7,13],[13,1],[14,17],[11,47],[12,26]],'unbroken',[[6,1]],'fceux',[[20,3],[22,6],[18,11],[21,1],[15,7],[2,2],[8,1],[9,2],[3,1],[24,6],[4,5],[10,6],[25,1],[5,10],[19,4],[23,7],[12,13],[11,11]],'logs',[[22,1]],'principle',[[22,1],[6,1]],'exiting',[[15,1],[23,1]],'montage',[[23,1]],'controller',[[22,2],[11,4]],'conflicting',[[5,1]],'patern',[[23,1]],'across',[[4,1],[23,1]],'pay',[[8,1]],'tasers',[[11,2],[12,1],[14,5],[20,1],[22,2],[5,3],[2,1],[1,1],[7,8],[8,2],[6,8]],'count',[[25,1]],'checkpoint',[[6,2]],'researcher',[[2,1]],'classes',[[23,1]],'don',[[6,16],[22,1],[18,3],[2,2],[8,4],[9,2],[3,1],[24,4],[4,5],[10,1],[5,2],[23,1],[14,3],[7,4],[11,9],[12,9]],'inactive',[[22,1],[5,1]],'mentally',[[4,1],[2,2]],'outline',[[14,1]],'flashing',[[22,1],[23,2],[5,1]],'match',[[19,1],[22,2],[24,2],[25,2],[12,3],[6,2]],'restores',[[22,3]],'subsegment',[[22,2],[6,1]],'thought',[[10,1],[6,1]],'smoothly',[[2,1]],'unwittingly',[[7,1]],'retrieve',[[18,1]],'also',[[6,10],[20,1],[18,3],[22,40],[16,4],[15,7],[2,4],[8,3],[9,3],[3,3],[24,4],[4,7],[10,4],[25,1],[5,10],[19,2],[23,18],[14,4],[7,4],[11,12],[12,12]],'designed',[[22,2],[14,1],[2,1],[23,1]],'the',[[22,1483],[11,378],[18,46],[6,393],[15,262],[2,123],[8,162],[9,280],[3,52],[25,143],[7,227],[1,12],[13,3],[16,203],[21,17],[17,227],[24,199],[4,292],[10,238],[5,569],[19,84],[0,5],[23,134],[14,141],[12,358],[20,149]],'mechanically',[[7,1],[2,1],[8,2],[6,1]],'corners',[[4,1]],'remind',[[11,2],[25,1]],'overcoming',[[6,1]],'falling',[[6,1]],'cached_first_difference',[[23,1]],'map',[[22,1],[23,2],[11,2],[15,2]],'interactive',[[0,1],[2,1]],'interim',[[10,1],[7,3],[2,1],[14,2],[9,1],[5,1]],'enjoy',[[6,2]],'accessing',[[19,1]],'display',[[22,14],[24,1],[10,2],[4,2],[16,1],[15,7],[23,1],[2,2],[11,5],[20,1]],'int',[[22,2],[18,48],[20,1]],'increased',[[9,1],[6,1]],'loads',[[22,2],[24,1],[14,1],[7,4],[23,12]],'occasionally',[[22,1],[15,1]],'obstacles',[[6,3]],'paging',[[16,2]],'not',[[6,17],[20,3],[18,25],[22,70],[16,2],[15,7],[17,14],[2,13],[8,2],[9,8],[24,9],[4,5],[10,8],[25,9],[5,7],[19,2],[23,9],[14,5],[7,6],[11,9],[12,19]],'none',[[24,1],[11,1]],'normally',[[10,1],[14,3],[9,1],[5,1]],'minimap',[[22,16]],'bookmarkx',[[25,1]],'title',[[0,1],[4,1],[10,3]],'realize',[[10,1],[2,1]],'sole',[[4,1]],'scripting',[[5,2]],'alternate',[[12,1],[10,1],[8,1],[11,4],[5,1]],'score',[[24,1],[14,1]],'cfg',[[11,1],[23,2]],'identification',[[2,1]],'unobtrusively',[[4,1]],'slower',[[6,1]],'abandon',[[6,1]],'model',[[6,1]],'maintain',[[12,1],[6,1]],'intensified',[[7,1]],'dot',[[15,1],[25,1]],'try',[[6,6],[20,1],[2,3],[8,2],[9,4],[24,1],[4,3],[10,3],[5,3],[19,2],[14,3],[7,2],[11,1],[12,3]],'fastest',[[24,1],[14,2],[13,1],[20,3],[6,1]],'overwriting',[[11,1],[5,1]],'colored',[[19,2],[22,7],[16,1],[5,3]],'evolved',[[22,1],[2,2]],'import',[[17,4],[19,5],[4,1],[22,1],[12,2],[23,1]],'si_gamepad',[[25,4]],'launching',[[22,1],[24,3],[2,1],[12,1],[23,5]],'doubting',[[6,1]],'integrity',[[25,1]],'absolutely',[[4,1]],'asking',[[11,1],[18,3]],'ask',[[19,1],[12,2],[23,1]],'thread',[[22,1]],'surroundings',[[11,1]],'invokes',[[23,1]],'meaningful',[[11,1]],'markedframe',[[18,2]],'verbal',[[6,1]],'wasting',[[7,1]],'3000',[[24,1]],'2nd',[[22,4],[10,1],[25,3],[5,3],[19,1],[7,2],[11,2],[6,5]],'rare',[[22,1],[11,1],[7,2]],'returned',[[22,1],[18,1],[23,1]],'create',[[6,3],[20,1],[18,2],[22,4],[16,1],[2,2],[8,5],[3,1],[24,3],[4,1],[10,1],[5,4],[19,4],[23,4],[14,1],[1,1],[7,2],[11,5],[12,4]],'shortage',[[14,1]],'pageup',[[15,3]],'objectively',[[2,1]],'thanks',[[22,3],[11,3],[24,2],[5,2],[2,4],[20,1],[6,1]],'increasing',[[11,1],[14,1]],'rut',[[2,2]],'flexibly',[[22,1],[5,1]],'determining',[[25,1]],'superimposes',[[12,1]],'requested',[[18,2]],'adjacent',[[22,2],[7,2],[16,1],[6,1]],'constitutes',[[12,1]],'bumps',[[9,1]],'documentation',[[16,1],[15,2],[5,1],[21,1],[0,1],[25,1],[14,1],[1,1],[13,1],[12,3],[6,2]],'applyinputchanges',[[17,4],[22,1],[18,10],[12,2]],'green',[[9,5],[22,21],[4,4],[15,3],[5,2],[11,4],[20,4]],'remote',[[5,1],[2,1]],'cancel',[[22,1],[24,7],[4,1],[15,2],[23,3],[5,2],[11,2]],'minutes',[[5,1],[10,2],[11,3],[6,1]],'figure',[[4,1],[10,1],[8,1],[9,1]],'paper',[[14,1]],'implies',[[22,1],[6,2]],'listed',[[12,1],[4,1],[11,1]],'radiobuttons',[[15,1]],'each',[[22,26],[11,4],[18,2],[6,2],[2,1],[3,1],[24,1],[4,4],[25,5],[5,4],[23,1],[7,2],[14,1],[12,6],[20,2]],'fuzzy',[[22,1],[4,1],[6,2]],'carelessly',[[7,1]],'notify',[[24,1],[23,1]],'splicing',[[17,1],[5,1],[25,1],[23,1]],'moment',[[22,6],[18,5],[16,2],[15,2],[8,1],[9,1],[24,1],[4,2],[10,2],[5,2],[23,2],[7,1],[14,3],[11,2],[6,6]],'occurrence',[[20,6],[23,2]],'teacher',[[10,1]],'structurizing',[[12,1]],'applying',[[6,1],[18,2],[5,1],[7,1],[14,2],[8,1],[11,1],[9,1]],'variety',[[22,1],[14,1]],'derived',[[14,1]],'marking',[[9,1],[6,2]],'trouble',[[6,1]],'pairs',[[25,2]],'recent',[[3,1],[6,1],[4,1],[22,1],[24,2],[16,2],[23,1],[8,1],[11,1],[9,1]],'translucency',[[22,1]],' any',[[15,1],[25,1]],'tedious',[[14,1],[2,1]],'tree',[[22,9],[24,4],[16,2],[15,3],[5,7],[17,3],[19,1],[23,5],[2,2]],'sourceforge',[[21,1]],'damaged',[[12,1]],'issues',[[13,1]],'bookmark1',[[17,2]],'issue',[[19,1],[6,1]],'hoping',[[22,1]],'greater',[[14,1],[22,1],[5,1]],'various',[[6,2],[12,3],[4,2],[22,1],[2,1],[8,1],[11,2],[9,1]],'indicator',[[22,2],[23,1],[5,1]],'since',[[22,11],[6,4],[15,1],[2,2],[8,3],[9,3],[24,7],[10,1],[5,2],[19,3],[23,2],[7,2],[11,4],[12,4]],'lose',[[22,4],[18,2],[10,1],[9,3]],'grows',[[6,2]],'coded',[[11,1]],'20th',[[4,1]],'newcomers',[[2,2]],'ideas',[[12,1],[22,9],[10,4],[21,2],[5,1],[0,1],[2,1],[7,2],[8,3],[9,3],[6,2]],'separate',[[9,1],[12,1],[22,2],[5,1],[2,1],[7,1],[11,2],[6,2]],'int32',[[25,4]],'played',[[14,1],[22,1],[4,1],[24,1],[16,5],[25,1],[5,3],[2,2],[7,1],[8,1],[9,1],[6,2]],'memories',[[4,1],[2,1]],'dry',[[6,1]],'mapped',[[15,2],[11,2],[5,1]],'independently',[[22,1],[24,1],[11,1],[5,1]],'preparation',[[12,1]],'among',[[22,1],[23,1],[14,2],[7,1],[12,1],[15,2]],'idea',[[12,1],[22,2],[4,1],[10,1],[5,1],[2,1],[7,2],[11,2],[6,7]],'collected',[[22,2]],'superimpose',[[17,2],[22,1],[18,1],[2,1],[12,2],[5,4]],'intended',[[22,3],[2,1],[14,1],[21,1],[12,1],[11,4]],'remake',[[22,1]],'conducting',[[7,1]],'movies',[[22,3],[24,1],[4,1],[5,2],[19,3],[14,3],[12,2]],'textbook',[[1,1]],'fall',[[8,1]],'completing',[[20,1]],'humans',[[14,2]],'stumbling',[[7,1]],'unlike',[[12,1],[4,2],[14,3],[9,1],[5,2]],'carefree',[[6,1]],'twin',[[12,1]],'compressed',[[22,8],[24,1],[11,2],[23,1]],'heirs',[[22,1]],'four',[[22,1],[24,1]],'nothing',[[22,1],[4,1],[14,1],[18,8],[15,1]],'mistakes',[[6,4],[7,12],[2,3]],'columns',[[19,2],[22,61],[4,2],[23,2],[15,2],[5,3]],'down',[[6,2],[22,22],[18,3],[16,12],[15,16],[17,5],[2,1],[8,1],[9,4],[24,2],[4,12],[10,1],[25,3],[5,18],[19,1],[14,2],[11,8],[12,3]],'double',[[15,3],[17,7],[4,5],[22,4],[11,2],[5,1]],'turning',[[6,1]],'something',[[12,2],[2,2],[11,1],[6,2]],'stay',[[3,1],[11,1],[6,1]],'lay',[[8,1],[7,1]],'logged',[[22,3],[24,1],[5,1]],'reject',[[9,1]],'summer',[[22,1]],'scroll',[[22,5],[4,1],[10,1],[16,11],[15,11],[5,3],[7,1],[11,2],[9,1]],'numbered',[[22,1],[4,1],[14,1],[5,1]],'subtitled',[[12,1]],'implemented',[[22,3],[10,1],[2,1],[23,1]],'synopsis',[[13,1],[0,1],[20,2]],'esc',[[15,2],[4,1],[11,1],[5,2]],'takes',[[6,1],[22,6],[16,2],[5,1],[19,1],[7,1],[12,1],[11,2]],'physics',[[6,1]],'erased',[[17,1]],'desync',[[14,2]],'outdated',[[22,2]],'submitinsertframes',[[17,1],[18,2]],'definition',[[23,1]],'advance',[[9,1],[16,1],[15,3],[5,3],[17,1],[19,1],[2,1],[14,2],[8,2],[11,3],[12,2]],'decisions',[[8,2],[10,3],[6,2]],'take',[[12,1],[22,2],[4,1],[10,1],[5,1],[23,4],[7,1],[14,1],[8,1],[11,3],[6,5]],'cleared',[[22,1],[4,1],[11,3]],'remove',[[6,1],[22,3],[4,5],[10,1],[15,7],[23,1],[17,7],[11,4],[9,1]],'arrange',[[4,1]],'recognized',[[4,1]],'associate',[[6,1],[4,1],[2,1]],'functions',[[3,2],[22,6],[18,5],[24,1],[15,2],[5,3],[23,1],[2,1],[7,1],[13,1],[12,4],[11,1]],'producer',[[15,1],[23,1]],'coloring',[[22,3],[4,1]],'substantial',[[11,1],[14,1]],'generation',[[22,1]],'differ',[[22,1],[24,1],[4,1],[12,1],[11,1]],'restoring',[[22,1],[23,4],[14,1]],'suggested',[[24,1]],'establishes',[[14,1]],'combined',[[17,2],[22,1],[5,1]],'counts',[[14,1]],'decides',[[7,1]],'practical',[[10,1],[14,1],[15,1],[6,1]],'bonus',[[9,1],[6,1]],'imagining',[[6,1]],'initialization',[[17,3],[23,2]],'those',[[6,3],[22,3],[18,2],[15,5],[17,3],[2,1],[9,1],[3,3],[4,2],[25,1],[5,4],[19,1],[7,2],[14,6],[11,4],[12,3]],'successors',[[22,1]],'deciphering',[[12,1]],'descending',[[5,1]],'interconnected',[[14,1]],'received',[[14,2]],'individuality',[[6,1]],'getnote',[[18,2]],'recording',[[6,2],[22,8],[15,3],[17,4],[2,2],[8,9],[9,1],[3,2],[24,6],[10,1],[5,18],[19,3],[23,6],[14,5],[7,5],[11,15],[12,1]],'rewinding',[[16,2],[15,1],[23,1]],'cutscenes',[[6,1]],'unneeded',[[20,1]],'skilled',[[2,1]],'techniques',[[20,1],[7,1]],'unbounded',[[5,1]],'repository',[[21,1],[2,1]],'sequentially',[[14,2],[7,1]],'erroneous',[[7,1]],'unnoticed',[[7,1]],'appearing',[[5,1],[12,1],[9,1],[6,1]],'vice',[[22,1],[16,1],[15,1]],'rapid',[[8,1]],'mainly',[[22,1],[7,1]],'assuming',[[23,1]],'backup_bookmarks',[[23,1]],'enjoyment',[[6,1]],'essence',[[6,1],[19,1],[2,1]],'thoughts',[[10,1],[7,1],[2,1],[12,1]],'generally',[[19,1],[10,1],[14,1],[7,1]],'constrained',[[11,1]],'aspects',[[12,2],[18,1],[2,3],[14,2],[11,1],[6,1]],'increase',[[6,1],[22,9],[4,1],[15,1],[2,1],[8,1],[12,9],[11,3]],'importantly',[[12,1],[23,1]],'bookmarking',[[22,3]],'tap',[[15,2],[4,1],[5,1]],'min',[[23,1]],'more',[[6,11],[20,3],[18,1],[22,14],[16,1],[15,1],[21,1],[17,2],[2,7],[8,4],[9,6],[24,1],[4,4],[10,7],[5,3],[23,1],[14,22],[7,8],[11,11],[12,7]],'events',[[6,3],[22,5],[16,5],[2,5],[8,1],[9,3],[4,5],[10,3],[5,7],[19,1],[14,7],[7,3],[11,3],[12,3]],'live',[[14,1],[6,1]],'quickly',[[6,2],[22,7],[16,2],[15,2],[2,5],[8,4],[9,1],[4,2],[10,2],[5,4],[19,1],[11,5],[12,1]],'dealing',[[11,1],[6,1]],'beating',[[2,1]],'particularly',[[24,1],[11,1]],'nuances',[[21,1]],'breaking',[[14,1]],'rectangular',[[22,4]],'extension',[[24,1],[2,1],[12,1],[25,1]],'revealed',[[7,1],[6,1]],'occupy',[[11,1]],'bring',[[6,2],[24,1],[4,1],[15,2],[7,1],[12,2],[9,1]],'asked',[[18,1]],'forgotten',[[4,1],[20,1]],'weigh',[[10,1],[8,1],[9,1],[20,1]],'clicks',[[22,3],[24,1],[4,3],[10,1],[15,1],[23,8],[14,1],[11,2],[12,2]],'disregard',[[2,1]],'navigate',[[22,1],[15,1],[5,2],[7,2],[13,1],[8,3],[12,1]],'luascripts',[[12,1],[18,1]],'hotness',[[22,7],[11,4]],'progressbar',[[22,2],[23,2],[11,1],[15,1]],'push',[[24,1],[23,1]],'distinct',[[22,1],[12,1]],'900',[[8,3]],'behind',[[8,2],[4,1],[11,1]],'accumulate',[[6,1]],'reproducible',[[14,2]],'rerecord',[[22,3],[24,1],[15,2],[5,1],[23,1],[25,1],[7,1],[8,1],[6,1]],'programmed',[[12,1]],'hud',[[22,1],[14,1],[11,1],[23,1]],'case',[[6,3],[20,1],[22,4],[24,3],[5,3],[7,6],[14,1],[8,1],[12,4],[11,3]],'smart',[[6,1],[12,1],[5,1]],'group',[[6,2]],'downside',[[11,1],[7,1]],'meeting',[[22,2]],'filler',[[6,1]],'out',[[22,2],[24,1],[10,2],[5,1],[23,1],[7,2],[2,2],[8,3],[9,2]],'verify',[[7,1]],'rewriting',[[14,1],[7,2]],'plus',[[5,1],[22,1],[15,1],[11,1]],'transmission',[[7,1]],'variables',[[22,2],[12,3],[14,1]],'pacifist',[[14,1]],'detecting',[[7,1]],'disable',[[22,6],[4,1],[11,6],[23,1]],'execute',[[11,1],[18,1]],'names',[[22,3],[24,1],[2,1],[23,2]],'implied',[[22,1],[5,1]],'returning',[[22,1],[10,1],[16,2],[11,1],[5,4]],'checksum',[[24,5]],'knowledge',[[9,1],[6,1],[22,1],[7,1],[1,1],[14,5],[11,1],[12,2]],'resumed',[[22,1]],'ascending',[[22,1],[18,1]],'large',[[6,7],[22,1],[4,1],[19,1],[7,2],[12,2],[11,1]],'aim',[[24,1]],'interdependency',[[10,1]],'identifier',[[25,1]],'indeterminate',[[18,1]],'%01d',[[25,2]],'lowest',[[22,1]],'racing',[[20,1]],'reach',[[11,1],[4,1],[10,1],[5,1],[8,2],[9,2],[6,6]],'zipping',[[14,1]],'tens',[[16,2]],'onto',[[22,1],[6,1]],'sync',[[23,1],[12,1],[6,2]],'noticed',[[7,3],[4,1],[6,2]],'forces',[[6,1],[22,1],[5,1]],'inputting',[[10,1]],'public',[[12,1],[23,2]],'clearing',[[22,1],[4,1],[23,1]],'persistent',[[7,1]],'compares',[[22,3],[24,1]],'bookmark9',[[17,1]],'10px',[[22,2]],'supposedly',[[9,1]],'strict',[[5,1],[22,1],[2,1]],'solve',[[14,1]],'soon',[[22,1],[4,1],[10,1],[23,1]],'cool',[[4,1],[11,1]],'learn',[[12,1],[10,1],[0,1],[2,2],[1,1],[8,2],[9,1],[6,2]],'traditional',[[22,2],[6,3],[2,3],[8,6],[9,3],[10,2],[5,2],[19,2],[23,1],[14,2],[7,6],[11,6],[12,2]],'multitrack',[[22,2],[5,1]],'interacting',[[3,1]],'factor',[[10,1],[14,1],[12,1],[6,6]],'log',[[20,1],[22,52],[18,2],[16,1],[15,9],[17,5],[2,2],[8,1],[9,5],[24,1],[10,1],[25,11],[5,7],[23,6],[14,2],[7,1],[12,4],[11,11]],'accelerate',[[22,1],[12,3]],'divergence',[[7,1]],'saved',[[11,6],[22,13],[15,3],[17,3],[8,1],[9,1],[3,1],[24,1],[4,1],[25,10],[5,3],[7,1],[14,1],[12,8],[20,3]],'definitions',[[14,1]],'correct',[[7,3],[6,2]],'complexity',[[5,2],[20,1],[4,1],[9,1],[6,1]],'laconic',[[4,1]],'entry',[[22,2]],'consoles',[[22,1]],'effort',[[7,2],[8,1],[2,1]],'online',[[7,1]],'pasted',[[17,1],[5,1]],'navigation',[[22,10],[16,10],[15,2],[2,1],[8,7],[9,3],[24,2],[4,2],[10,3],[5,3],[19,1],[0,1],[23,2],[14,5],[13,1],[7,8],[11,5]],'random',[[14,1]],'branch6',[[17,2]],'certain',[[11,3],[12,4],[10,1],[22,4],[5,1],[23,1],[2,1],[14,5],[8,1],[9,1],[6,3]],'truth',[[6,1],[2,1]],'didn',[[22,1],[18,1],[17,1],[2,2],[8,1],[9,1],[4,2],[10,1],[25,1],[5,1],[14,1],[20,1],[11,1]],'launch',[[3,2],[12,1],[24,2],[15,4],[23,1],[20,1],[11,3]],'blank',[[9,1],[22,2],[18,2],[24,2],[15,2],[5,2],[17,5],[12,1],[11,4]],'death',[[9,1],[7,1]],'backup_current_branch',[[23,1]],'combining',[[22,1]],'invent',[[14,1],[12,2],[7,1]],'compress',[[24,1]],'201',[[8,2]],'implements',[[22,1],[8,1],[23,38]],'shine',[[11,1]],'newline',[[25,1]],'subforum',[[19,1]],'cons',[[10,1],[7,1],[14,2],[8,1],[9,1],[11,1]],'assumption',[[22,1],[14,1]],'neighborhood',[[15,1]],'tied',[[22,1],[4,1],[5,1]],'damage',[[12,2],[14,1]],'hastily',[[7,1]],'becomes',[[20,1],[22,6],[4,2],[16,1],[5,1],[17,2],[2,1],[7,2],[11,1],[6,3]],'corruptor',[[17,1]],'subpixels',[[14,2]],'would',[[22,4],[6,3],[15,1],[2,4],[9,1],[10,2],[5,2],[19,1],[23,3],[7,3],[14,3],[11,4],[12,3]],'hierarchy',[[22,2],[5,2]],'recorder',[[22,9],[23,7],[18,2],[12,1],[5,9]],'scheme',[[19,1],[7,1],[11,3],[5,1]],'divides',[[6,1]],'helpndoc',[[22,1],[11,1],[18,1],[6,1],[15,1],[2,1],[8,1],[9,1],[3,1],[25,1],[7,1],[1,1],[13,1],[16,1],[21,1],[17,1],[24,1],[4,1],[10,1],[5,1],[19,1],[0,1],[23,1],[14,1],[12,1],[20,1]],'setselection',[[18,3]],'exporting',[[3,1]],'340',[[6,2]],'entangle',[[14,1]],'new_set',[[18,2]],'read',[[22,2],[6,2],[18,2],[15,1],[8,1],[3,2],[25,1],[5,3],[23,3],[0,1],[7,10],[14,1],[12,2],[11,4]],'increases',[[6,1],[11,1],[22,1],[2,1],[9,1],[5,1]],'indeed',[[24,1],[7,1],[11,1],[6,1]],'drag_mode_selection',[[24,1]],'profit',[[6,1]],'goals',[[2,1],[1,1],[7,1],[12,1],[6,2]],'collision',[[9,1],[14,1]],'copying',[[19,1],[22,1],[23,8]],'offset',[[25,2]],'translate',[[12,1]],'connection',[[9,1]],'event',[[6,13],[20,17],[22,4],[16,1],[2,1],[8,3],[9,9],[4,1],[10,2],[5,1],[14,2],[7,1],[11,1],[12,2]],'joypad',[[22,30],[4,2],[18,10],[25,2],[23,2],[17,1],[7,3],[2,1],[11,6],[12,4]],'interpreter',[[22,4]],'using',[[6,6],[20,8],[18,2],[22,13],[16,2],[15,9],[17,6],[2,6],[8,7],[9,4],[24,1],[4,1],[10,4],[25,1],[5,12],[19,3],[23,1],[14,8],[1,1],[7,10],[11,5],[12,11]],'instead',[[11,3],[22,7],[18,1],[15,3],[17,1],[9,2],[24,1],[4,2],[5,6],[19,1],[23,1],[7,5],[14,1],[20,1],[6,4]],'induces',[[10,1]],'inconvenience',[[11,1]],'translucent',[[22,1]],'begins',[[22,2]],'detachment',[[9,1]],'separately',[[2,1],[14,1],[8,1],[11,2]],'years',[[6,1]],'affected',[[5,1],[22,3],[16,1],[9,1],[6,1]],'|commands|rldutsba|rldutsba|rldutsba|rldutsba|port2|',[[25,1]],'allow',[[22,3],[24,1],[10,2],[14,2],[11,1],[23,2]],'occasions',[[22,1]],'conclusion',[[22,1],[6,1]],'perfectly',[[8,1],[12,1],[6,1]],'experiment',[[11,2],[4,1],[10,1],[5,2],[2,1],[8,1],[9,1],[6,1]],'tough',[[8,1]],'task',[[7,2],[14,6],[16,1],[12,5],[6,5]],'easiest',[[20,1]],'worth',[[6,1]],'zeroth',[[17,1],[22,2],[4,1],[18,1],[11,1]],'inconveniences',[[12,1]],'per',[[22,1],[23,1],[10,1],[14,1],[18,7],[5,1]],'inspection',[[2,1]],'dozens',[[12,1]],'swapped',[[22,1]],'original',[[22,2],[6,1],[24,1],[7,1],[2,1],[11,2],[9,1]],'2013',[[22,1],[11,1],[18,1],[6,1],[15,1],[2,1],[8,1],[9,1],[3,1],[25,1],[7,1],[1,1],[13,1],[16,1],[21,1],[17,1],[24,1],[4,1],[10,1],[5,1],[19,1],[0,1],[23,1],[14,1],[12,1],[20,1]],'fourscore',[[12,1],[25,7]],'natural',[[20,1],[2,1],[12,1],[6,1]],'instance',[[23,17],[4,1],[2,1],[11,1],[6,1]],'prompting',[[12,2]],'dump',[[4,1],[12,1]],'older',[[2,1]],'precise',[[10,1],[4,1],[6,1]],'cycle',[[8,1]],'empty',[[22,7],[4,4],[18,1],[15,4],[23,2],[17,3],[19,1],[25,1],[11,3]],'accessed',[[3,1]],'modify',[[19,1],[4,1],[7,1],[12,5],[6,1]],'discomfort',[[4,1]],'contain',[[22,4],[24,1],[4,1],[15,1],[25,7],[14,1],[12,1],[6,3]],'tactic',[[6,1]],'current',[[6,27],[20,7],[18,12],[22,70],[16,8],[15,11],[17,7],[2,3],[8,14],[9,8],[3,2],[24,8],[10,8],[25,3],[5,20],[19,3],[23,26],[14,10],[7,11],[11,9],[12,11]],'show',[[22,2],[6,1],[10,2],[15,3],[23,1],[12,1],[11,2]],'adv',[[15,1]],'anytime',[[4,2],[5,1]],'romchecksum',[[25,1]],'allowing',[[12,2],[14,1],[10,1],[22,3],[16,1],[5,2],[2,2],[7,2],[8,2],[11,3],[6,1]],'but',[[6,23],[20,3],[22,41],[16,2],[15,1],[17,2],[2,11],[8,8],[9,10],[24,3],[4,12],[10,9],[25,1],[5,15],[19,2],[23,2],[14,6],[7,13],[11,18],[12,22]],'achieving',[[7,1]],'intent',[[12,1]],'adds',[[25,1]],'joysticks',[[23,1]],'backward',[[14,1]],'chooses',[[14,1]],'rate',[[5,1]],'meantime',[[5,1]],'fireball',[[22,5],[23,1],[16,1],[5,2]],'launched',[[12,1],[10,1],[2,1]],'home',[[22,1],[24,1],[16,3],[15,3],[5,2]],'forced',[[14,1],[6,2]],'simultaneously',[[22,1],[14,1],[2,1],[9,1],[20,2]],'throws',[[6,1]],'gives',[[22,1],[11,1]],'memo',[[25,1]],'level',[[22,6],[11,3],[6,16],[16,1],[2,3],[8,3],[4,3],[10,3],[25,2],[5,8],[7,4],[12,7],[20,2]],'autoscrolling',[[11,1]],'easily',[[20,1],[22,2],[4,1],[16,1],[5,1],[2,1],[14,1],[8,1],[12,1],[11,1]],'fully',[[23,1]],'copy',[[22,8],[16,1],[15,4],[17,1],[2,1],[8,2],[3,1],[5,3],[19,3],[23,2],[14,1],[7,4],[11,1],[12,7]],'columnset',[[23,1]],'states',[[22,4],[4,3],[25,1],[23,1],[5,1],[14,1],[12,1]],'border',[[22,2],[24,1]],'flying',[[9,1]],'lines',[[6,1],[22,28],[4,7],[25,2],[5,2],[17,2],[12,2],[11,8]],'remain',[[22,4],[12,1],[6,1]],'painted',[[22,2]],'happen',[[20,1],[2,1],[15,1],[5,1]],'reorder',[[22,1]],'processed',[[4,2]],'pointed',[[22,3],[15,1],[7,1]],'scrolling',[[6,1],[22,8],[4,1],[16,4],[15,4],[5,1],[19,1],[23,5],[12,2],[9,1]],'yes',[[22,2],[24,4],[12,1]],'asterisk',[[3,1],[22,1],[11,1],[12,1]],'taseditor_lua',[[22,1],[23,1]],'reverse',[[18,1]],'adequate',[[23,1],[6,3]],'replay',[[11,1],[12,1],[4,1],[10,2],[20,1],[5,2],[19,1],[23,2],[7,3],[14,1],[9,3],[6,1]],'corruption',[[14,1]],'represent',[[5,2],[22,1],[14,1],[25,3],[6,1]],'fact',[[11,1],[6,3],[22,1],[24,1],[23,1],[7,1],[14,1],[12,2],[20,1]],'reminding',[[11,1]],'toolbox',[[3,1],[22,1],[4,1],[16,1],[5,4],[14,6],[12,1]],'joypad1data',[[12,3]],'habitual',[[7,1],[6,1]],'time',[[6,16],[20,11],[18,3],[22,23],[16,4],[15,2],[17,3],[2,6],[8,6],[9,12],[4,5],[10,8],[5,25],[23,6],[0,1],[7,6],[13,1],[14,14],[11,11],[12,10]],'plug',[[19,1],[5,1]],'acceptable',[[6,1]],'feasible',[[14,1]],'slow',[[10,1],[15,1],[5,2],[2,1],[14,2],[8,1],[9,1]],'neighbors',[[22,1],[14,1]],'mimic',[[14,1]],'gathered',[[6,1]],'our',[[6,1],[20,1],[2,1]],'upload',[[2,1]],'containers',[[14,1]],'numeration',[[4,1]],'medium',[[14,2]],'targeting',[[22,1]],'eliminate',[[14,1],[6,1]],'selectall',[[24,1]],'voiced',[[2,1]],'detected',[[19,1],[22,2],[9,2],[20,2]],'majority',[[22,1],[7,2],[11,1],[6,1]],'bookmark8',[[17,1]],'taseditor',[[22,43],[11,36],[18,57],[6,3],[15,3],[2,14],[8,3],[9,5],[3,7],[25,10],[7,9],[1,1],[13,1],[16,1],[21,5],[17,13],[24,39],[4,10],[10,3],[5,14],[19,5],[0,2],[23,23],[14,6],[12,26],[20,2]],'individually',[[22,1],[6,2]],'borrow',[[6,1]],'inputted',[[14,1]],'perform',[[4,1],[12,1]],'modifies',[[22,1]],'настройки',[[22,1]],'redrawing',[[23,8]],'freeze',[[5,1]],'third',[[5,2],[22,2],[7,1],[12,1],[6,1]],'cuts',[[14,1],[6,1]],'keyboard',[[22,4],[4,3],[15,7],[5,10],[19,1],[23,1],[2,2],[7,3],[11,5]],'submits',[[12,1]],'invoked',[[19,1]],'commenting',[[12,1]],'filling',[[22,2]],'hence',[[22,1]],'measuring',[[6,1],[14,2],[5,1]],'converting',[[22,2]],'methodology',[[0,1],[7,2],[1,1],[14,3],[20,2]],'viewpoint',[[2,1]],'stretch',[[22,5],[4,1],[15,1],[5,1]],'image',[[22,3],[10,1],[4,4],[14,1],[20,1],[6,1]],'successful',[[20,1],[10,2],[7,2],[14,1],[8,2],[9,2],[6,1]],'fined',[[2,1]],'actively',[[24,1]],'rethink',[[7,1],[6,1]],'play',[[14,2],[20,1],[24,3],[16,1],[15,2],[5,5],[2,3],[7,3],[8,1],[11,1],[6,5]],'pipes',[[6,3]],'interesting',[[20,1],[10,1],[2,1],[12,1],[6,1]],'automate',[[18,1],[5,1]],'zero',[[22,3],[18,2],[2,1],[6,3]],'recall',[[11,3]],'smaller',[[14,1],[22,1],[6,1]],'found',[[22,8],[11,1],[18,2],[6,4],[3,1],[24,1],[4,2],[10,1],[5,1],[19,2],[23,2],[7,1],[12,3],[20,4]],'accumulated',[[12,1]],'phenomenon',[[6,1]],'arranged',[[22,1]],'dirty',[[12,1]],'sonic',[[14,1]],'loop',[[14,2],[12,3],[7,1]],'attempt',[[24,3],[7,1],[11,1],[5,1]],'responsive',[[4,1]],'activate',[[15,1],[4,3],[12,1]],'signal',[[22,2],[24,1]],'interconnection',[[9,1],[10,1]],'evolutionary',[[7,1]],'mouseover',[[23,4]],'optionally',[[15,1],[23,1]],'instantly',[[20,1],[22,3],[10,1],[18,1],[5,4],[7,1],[2,1],[14,1],[12,4],[11,1]],'works',[[6,1],[24,2],[10,2],[16,2],[15,1],[5,1],[17,1],[14,1],[12,1],[11,3]],'point',[[22,4],[11,4],[6,3],[16,1],[15,5],[2,1],[8,1],[4,3],[10,1],[23,6],[7,2],[12,1],[20,1]],'attention',[[22,3],[24,1],[10,2],[5,1],[2,1],[14,1],[11,1]],'expose',[[6,1]],'messages',[[23,2],[24,1],[4,1],[12,2],[11,1]],'conjecture',[[7,1]],'rollback',[[23,3]],'external',[[6,1],[22,1],[25,1],[23,2],[14,1],[7,1],[2,1],[8,1],[12,1]],'insertion',[[22,1],[18,1],[23,1]],'human',[[22,1],[14,2],[2,1],[20,2],[6,3]],'earlier',[[6,3],[22,3],[20,1],[11,2]],'timesaver',[[14,3]],'automatism',[[12,1]],'understanding',[[11,1],[6,1]],'second',[[22,14],[6,3],[18,5],[2,1],[9,1],[4,1],[10,2],[5,1],[19,1],[23,1],[14,1],[11,4],[12,7]],'purpose',[[22,1],[14,1],[11,1],[5,2]],'wrote',[[11,1],[12,1]],'specs',[[14,6]],'resource',[[22,1],[23,1]],'shortcuts',[[19,1],[2,1]],'arrow',[[22,21],[24,1],[4,2],[15,4],[5,1],[14,1],[20,4],[9,5]],'memorizes',[[22,2]],'still',[[6,4],[22,4],[18,2],[17,1],[2,5],[8,1],[9,3],[24,1],[4,1],[10,2],[5,1],[19,1],[7,3],[11,2],[12,5]],'latter',[[11,1],[14,1]],'half',[[5,4],[17,2],[18,1],[22,5],[15,1],[6,5]],'bad',[[12,1],[6,1]],'customize',[[19,1],[22,3],[14,1],[11,1]],'watched',[[22,2]],'tested',[[20,1],[5,1]],'could',[[12,1],[22,3],[4,1],[5,2],[7,1],[14,1],[8,1],[9,1],[6,1]],'tinted',[[22,1]],'deselected',[[22,1]],'reselect',[[15,1],[23,1]],'addresses',[[12,3]],'workflow',[[22,2],[11,1]],'sounded',[[22,1]],'hot',[[19,1],[22,11],[4,2],[11,7],[23,7]],'videos',[[14,2],[6,1]],'delay',[[14,1],[23,1],[7,1]],'arcade',[[15,1]],'parsed',[[25,2]],'viewer',[[15,2]],'deeper',[[10,1]],'micro',[[6,1]],'foresight',[[6,1]],'sorted',[[18,2]],'documenting',[[11,1],[2,1]],'tasing',[[12,6],[20,5],[18,1],[22,7],[16,1],[15,1],[2,24],[8,7],[9,8],[3,1],[4,1],[10,8],[5,10],[19,2],[0,3],[23,4],[7,16],[1,5],[14,14],[11,7],[6,24]],'rules',[[7,1],[12,1],[2,6]],'called',[[6,1],[22,6],[4,3],[18,5],[16,1],[5,1],[14,3],[12,2],[11,1]],'parameters',[[22,2],[23,1]],'endeavors',[[19,1]],'lost',[[22,1],[8,1]],'indefinite',[[6,1]],'send',[[22,1],[24,1],[16,2],[15,6],[5,4],[23,2],[12,1],[11,1]],'order',[[6,8],[22,15],[18,2],[2,3],[8,4],[9,7],[24,3],[4,2],[10,1],[25,3],[23,1],[19,1],[14,1],[7,1],[11,5],[12,6]],'removes',[[24,1],[18,1],[5,2]],'draws',[[19,1],[24,1],[11,1],[12,2]],'intuition',[[14,1],[6,2]],'invalid',[[18,2]],'docs',[[0,1],[12,1]],'reselectclipboard',[[24,1]],'registered',[[22,2],[10,1],[18,10],[15,1],[23,2],[17,1],[12,2]],'extra',[[19,1],[11,1],[14,1]],'anywhere',[[17,3],[22,1],[4,2],[16,3],[15,3]],'kept',[[6,1],[11,1],[5,3]],'virtuosity',[[8,1]],'observed',[[14,1]],'professionnelle',[[2,1]],'accustom',[[8,2]],'beat',[[20,3],[22,1],[2,1],[12,1],[5,1]],'readability',[[2,2]],'glow',[[22,1]],'disposal',[[5,1]],'thousand',[[6,3]],'newcomer',[[2,1]],'curent',[[23,1]],'dontknow',[[22,1]],'width',[[22,14]],'commented',[[21,1],[12,1]],'stop',[[22,2],[24,2],[4,1],[10,1],[15,1],[5,2],[2,1],[9,1],[6,1]],'keypad',[[15,4]],'dead',[[14,1]],'best',[[6,9],[20,14],[10,5],[22,1],[24,1],[7,3],[14,6],[8,6],[12,1],[9,7]],'list',[[22,29],[18,5],[16,4],[15,8],[21,1],[17,4],[24,1],[4,2],[5,14],[19,1],[23,14],[13,1],[12,2],[11,2]],'reveal',[[7,1],[2,1],[14,1],[6,2]],'kinds',[[22,1]],'powered',[[20,1]],'segments',[[6,19],[20,7],[22,2],[16,3],[15,1],[2,1],[8,3],[9,3],[10,2],[5,2],[14,2],[7,4],[11,1],[12,7]],'designers',[[6,1]],'flexible',[[22,1]],'listview',[[22,3]],'accounted',[[11,1]],'dipswitch',[[24,1]],'learns',[[7,1]],'insert#4',[[17,1]],'newbie',[[6,1],[7,1],[2,2]],'unconventional',[[2,1]],'put',[[3,1],[11,1],[4,5],[10,1],[12,2],[21,1],[22,3],[5,1],[7,1],[8,1],[9,1],[6,1]],'effectively',[[24,1],[9,1]],'flaws',[[7,1],[6,1]],'battles',[[12,1]],'convert',[[12,2]],'local',[[3,1]],'generator',[[24,1],[0,1],[18,1],[25,1],[12,1],[5,1]],'port2',[[24,1],[25,3]],'pasting',[[12,1]],'blinking',[[5,3]],'eight',[[25,1]],'stage',[[22,1],[6,3]],'psychological',[[2,1]],'shift',[[9,5],[22,11],[4,4],[10,4],[16,13],[15,25],[5,16],[17,10],[11,3],[12,1]],'getselection',[[12,1],[18,2]],'composed',[[5,1]],'paste',[[22,1],[15,3],[5,2],[17,5],[19,1],[23,1],[7,1],[2,1],[8,1],[12,3]],'tick',[[22,1]],'coordinates',[[23,2],[12,2],[14,4]],'one',[[6,12],[20,5],[18,7],[22,32],[16,1],[15,3],[17,17],[2,4],[8,7],[9,4],[3,1],[24,4],[4,11],[10,3],[5,14],[19,1],[23,3],[14,9],[7,7],[11,4],[12,12]],'holding',[[11,1],[22,5],[10,1],[15,3],[5,2],[19,1],[2,1],[7,1],[9,4],[6,3]],'cross',[[22,1],[4,1]],'decided',[[19,1]],'counters',[[12,1]],'credible',[[2,1]],'formed',[[22,1]],'stumble',[[6,1]],'ignored',[[25,2]],'switching',[[22,1],[7,2],[2,1],[8,1],[11,1],[15,1]],'pointless',[[11,1]],'markers_manager',[[23,2]],'picture',[[3,1],[11,3],[4,4],[10,1],[12,2],[5,5],[2,1],[9,1],[6,3]],'topics',[[22,1]],'synchronously',[[10,1]],'undo',[[22,5],[6,1],[18,1],[15,3],[17,1],[2,1],[8,2],[3,1],[24,3],[4,1],[5,4],[23,6],[12,1],[11,10]],'strong',[[2,1]],'exits',[[22,1]],'trivial',[[6,1],[4,1],[2,1]],'subtasks',[[14,1],[6,1]],'self',[[4,1]],'aesthetic',[[22,1]],'observations',[[6,1]],'program',[[20,1],[22,7],[21,5],[15,1],[2,4],[3,6],[24,1],[4,1],[10,1],[5,1],[19,4],[0,2],[14,3],[1,3],[11,3],[12,1]],'sites',[[1,1],[8,1]],'single',[[6,3],[22,11],[16,2],[15,1],[21,1],[2,1],[9,4],[24,1],[4,5],[10,1],[5,3],[19,1],[23,18],[7,1],[14,2],[11,5],[12,4]],'cell',[[17,8],[22,30],[4,6],[16,5],[15,10],[11,3]],'directly',[[22,3],[7,2],[14,1],[12,1],[6,2]],'glossary',[[3,1],[0,1],[14,3],[13,1],[12,1]],'click',[[22,26],[16,15],[15,27],[17,34],[2,1],[9,1],[24,6],[4,26],[10,1],[5,21],[19,6],[23,2],[12,11],[11,8]],'pictures',[[11,1]],'organize',[[14,1]],'respects',[[24,1]],'new',[[6,17],[20,24],[18,4],[22,20],[16,2],[15,1],[17,15],[2,6],[8,5],[9,6],[3,1],[24,3],[4,4],[10,3],[25,1],[5,9],[19,5],[23,10],[7,3],[1,1],[14,1],[11,14],[12,8]],'though',[[19,1],[22,1],[24,2],[2,1],[12,2],[6,2]],'laws',[[14,1]],'assume',[[7,1],[9,1],[2,1]],'straightforward',[[12,1],[7,1]],'from',[[6,21],[22,64],[18,3],[16,9],[15,26],[21,1],[17,16],[2,11],[8,9],[9,7],[3,2],[24,14],[4,11],[10,5],[25,3],[5,26],[19,3],[23,32],[14,7],[7,15],[11,16],[12,17]],'gaming',[[2,1],[8,1],[11,1],[6,1]],'internet',[[12,1]],'much',[[12,3],[22,2],[4,1],[10,2],[24,1],[23,2],[2,2],[7,3],[11,5],[6,6]],'method',[[6,2],[22,2],[16,4],[2,3],[8,12],[9,11],[4,1],[10,18],[5,2],[14,1],[7,10],[11,2],[12,4]],'reloads',[[2,1]],'index',[[4,1],[18,11]],'400',[[11,1]],'turns',[[24,1],[4,1],[5,1],[2,1],[7,1],[14,1],[11,1],[6,1]],'handles',[[23,1]],'initial',[[22,4],[10,2],[7,1],[14,1],[12,1],[6,1]],'scope',[[6,1]],'underlying',[[22,1]],'enabled',[[22,1],[4,1],[10,1],[16,2],[5,1],[19,1],[11,30],[9,1]],'prepared',[[5,1],[22,1],[7,1],[6,1]],'outcome',[[7,6],[14,1],[8,2],[9,6],[6,1]],'markernum',[[17,1]],'memorized',[[22,1],[4,1]],'documents',[[16,1]],'centering',[[23,1]],'sends',[[22,5],[24,2],[18,4],[23,7]],'critical',[[11,1],[6,2]],'believes',[[22,1]],'oldest',[[23,1]],'temporary',[[8,1],[20,1]],'frequently',[[12,1]],'request',[[24,1],[18,9]],'manual',[[22,1],[6,1],[18,4],[15,2],[4,2],[5,1],[19,3],[0,3],[23,2],[7,1],[14,2],[12,2],[11,1]],'cursory',[[3,1],[4,1]],'segment',[[6,76],[20,11],[22,20],[16,20],[15,1],[2,1],[8,28],[9,34],[4,2],[10,27],[5,18],[14,7],[13,1],[7,21],[11,7],[12,21]],'imagine',[[12,1]],'uncommon',[[6,1]],'successfully',[[6,1],[22,1],[24,1],[23,1],[17,2],[7,1],[8,1],[20,1],[12,3]],'actions',[[12,3],[20,1],[4,1],[10,1],[22,1],[15,2],[5,2],[2,3],[7,1],[14,3],[11,2],[6,3]],'shouting',[[14,1]],'branch1',[[17,4]],'inspiration',[[7,1]],'replaces',[[22,1]],'priorities',[[4,1],[14,1]],'5000',[[24,1]],'producing',[[14,1]],'joypads',[[19,1],[22,5],[11,2],[23,1]],'throwing',[[22,1]],'rapidly',[[5,5]],'playing',[[11,5],[14,2],[20,4],[22,1],[24,3],[5,6],[0,1],[2,2],[7,3],[8,7],[9,1],[6,8]],'else',[[10,1],[14,2],[8,1],[11,1],[15,1]],'plastic',[[4,1]],'confirmation',[[12,1]],'characters',[[22,1],[25,2]],'taseditor_project',[[23,1]],'upper',[[22,4],[4,4],[16,2],[15,3],[5,5],[17,1],[19,1],[23,4],[14,1],[12,1],[11,3]],'menu',[[3,3],[22,3],[4,2],[24,7],[15,8],[5,6],[17,18],[19,9],[23,3],[12,3],[11,4]],'going',[[6,4],[12,4],[4,2],[10,1],[22,1],[16,2],[5,1],[11,2],[9,2]],'retreat',[[8,1],[7,1]],'covers',[[11,1]],'mapping',[[11,1]],'piano_rolx',[[25,1]],'macros',[[2,1]],'buttonpresses',[[22,2],[6,3],[15,1],[17,9],[9,1],[4,6],[10,2],[5,11],[19,3],[23,2],[7,4],[11,8],[12,2]],'loopholes',[[2,1]],'appropriate',[[22,8],[18,2],[14,1],[2,1],[5,1]],'visualize',[[5,1]],'others',[[3,1],[16,1],[12,1],[20,1]],'emulator',[[6,1],[22,18],[18,2],[16,4],[15,8],[21,1],[17,5],[2,3],[9,4],[3,4],[24,10],[4,8],[10,4],[25,5],[5,14],[19,1],[23,24],[7,3],[14,4],[11,13],[12,5]],'discuss',[[20,1]],'procedure',[[23,1]],'interprets',[[11,1],[7,1]],'branch8',[[17,2]],'moments',[[22,1],[7,2],[2,1],[8,1],[12,1],[6,3]],'romfilename',[[25,1]],'slows',[[22,1]],'existent',[[7,1]],'tried',[[11,1]],'ticks',[[15,1]],'actually',[[12,2],[10,1],[18,1],[15,1],[5,1],[17,1],[2,1],[7,3],[11,4],[6,1]],'honestly',[[12,1]],'registerafter',[[12,2]],'finds',[[12,1],[14,1]],'that',[[6,35],[20,6],[18,10],[22,65],[16,5],[15,9],[17,8],[2,10],[8,9],[9,12],[3,4],[24,16],[4,22],[10,7],[25,8],[5,25],[19,5],[23,14],[7,22],[13,1],[14,15],[11,24],[12,43]],'document',[[22,1],[6,2]],'presses',[[9,1],[6,1],[10,1],[18,1],[22,3],[5,2],[23,1],[14,1],[11,1],[12,3]],'interval',[[22,1],[12,3],[7,1]],'region',[[15,2],[23,4]],'reflecting',[[23,1]],'disregarded',[[22,1]],'presented',[[1,1],[5,1]],'variable',[[22,2],[12,1],[25,2]],'materials',[[20,1]],'while',[[6,5],[20,1],[18,2],[22,10],[15,7],[2,2],[8,7],[9,2],[3,1],[24,8],[4,6],[10,2],[5,5],[19,1],[23,1],[14,3],[7,3],[11,11],[12,8]],'invert',[[22,1]],'win32',[[21,1]],'pal',[[24,1],[18,1],[25,1]],'heart',[[7,1]],'usefulness',[[14,1]],'triangle',[[22,1],[24,1],[4,1]],'criterion',[[22,2],[10,2],[7,2],[14,2],[8,2],[9,3],[6,12]],'beginner',[[19,1],[0,1],[14,1],[1,2]],'move',[[6,3],[20,1],[18,2],[22,8],[16,13],[15,10],[2,2],[9,5],[3,1],[24,1],[4,3],[10,1],[5,4],[19,1],[23,1],[14,2],[11,1],[12,1]],'perfect',[[20,2],[10,1],[7,3],[12,1],[6,11]],'promising',[[22,1],[9,1],[20,1]],'deploy',[[23,1]],'inputlogs',[[23,2]],'supposed',[[5,1],[7,3],[14,1],[20,5],[6,3]],'fine',[[19,1]],'hex',[[15,1],[2,1]],'mathematical',[[12,1]],'focus',[[5,1],[22,1],[10,1],[23,1],[24,1],[6,4]],'accomplishes',[[6,1]],'guided',[[22,1]],'machine',[[15,1]],'focused',[[22,1],[24,1],[2,1]],'produce',[[25,1],[7,2]],' this',[[19,1]],'5th',[[4,1]],'bitmap',[[22,1]],'marker',[[6,5],[20,4],[18,10],[22,35],[16,15],[15,14],[17,57],[9,6],[3,1],[4,20],[5,10],[19,2],[23,9],[14,2],[12,7],[11,19]],'glitches',[[6,1]],'rides',[[5,1]],'darker',[[22,1],[11,1]],'pad',[[4,4],[5,1]],'example',[[6,11],[20,3],[18,2],[22,16],[2,2],[8,4],[9,5],[24,2],[4,7],[10,4],[25,2],[5,9],[19,1],[23,1],[14,3],[7,3],[11,8],[12,18]],'imposes',[[22,1]],'deselect',[[4,1],[15,1]],'subsegments',[[8,1],[20,1],[6,3]],'only',[[6,12],[20,6],[18,5],[22,29],[16,3],[15,7],[21,1],[17,2],[2,7],[8,6],[9,5],[24,5],[4,1],[10,8],[5,10],[19,2],[23,3],[14,5],[7,12],[11,17],[12,14]],'avert',[[7,1]],'negative',[[18,4]],'multitracking',[[22,2],[15,2],[5,2],[23,2],[2,1],[14,1],[8,1],[11,3]],'potential',[[9,1],[6,3]],'investigation',[[12,1]],'lengthy',[[19,1]],'expanding',[[11,1],[14,1]],'roulette',[[7,1]],'hundreds',[[11,1],[12,1]],'branch4',[[17,2]],'appear',[[6,2],[22,7],[18,1],[16,1],[17,2],[2,2],[9,1],[24,2],[4,3],[5,5],[19,1],[7,1],[14,3],[11,6],[12,4]],'complicated',[[6,1],[12,1],[2,1]],'coincides',[[22,1]],'files',[[3,1],[20,1],[24,3],[25,3],[5,1],[19,1],[23,4],[2,5],[1,1],[14,2],[12,4],[11,4]],'correction',[[7,4]],'surrounding',[[15,1]],'polling',[[14,2]],'fell',[[8,1],[5,1]],'synchronization',[[24,1]],'tasks',[[20,1],[10,1],[14,2],[12,3],[6,3]],'filter',[[22,1],[24,1],[10,1],[12,1],[9,1]],'unprohibited',[[14,1]],'compactly',[[17,1]],'snapshots',[[23,3]],'boss',[[12,5]],'poweron',[[18,1]],'truncation',[[17,1],[22,6]],'plans',[[5,1],[6,1],[2,1]],'shot',[[20,1],[4,1],[9,2]],'selections',[[22,3],[23,2]],'speedrun',[[6,5],[2,1],[7,1],[14,5],[20,1],[5,1]],'decreased',[[9,1]],'broken',[[6,1]],'ran',[[6,1]],'optimization',[[7,2],[14,2],[12,2],[6,3]],'expressions',[[12,1]],'launches',[[23,2]],'hotkeys',[[5,2],[15,10],[23,1],[24,3],[11,11],[9,3]],'costs',[[11,1],[12,1]],'requests',[[12,1],[18,6]],'previous',[[6,7],[20,3],[22,12],[16,7],[15,5],[8,3],[9,5],[24,1],[4,2],[10,4],[5,2],[23,1],[7,5],[14,2],[11,3],[12,4]],'vague',[[23,1],[4,1],[12,1],[6,1]],'accuracy',[[2,1]],'alternation',[[12,1],[9,1],[11,2]],'emulators',[[19,1],[22,2],[18,1],[14,4],[8,1],[11,1]],'minimize',[[14,1]],'bookmark6',[[17,1]],'reducing',[[22,1],[14,1],[2,1],[5,1]],'ineffectively',[[2,1]],'compresses',[[11,1],[23,1]],'joining',[[2,1]],'result',[[20,4],[6,4],[22,4],[17,4],[2,4],[8,8],[9,11],[24,1],[10,12],[19,1],[14,2],[7,7],[11,4],[12,5]],'suitable',[[10,2],[6,2]],'future',[[6,1],[22,7],[10,1],[14,1],[8,1],[11,1],[9,1]],'rarefication',[[11,1]],'ratio',[[9,1]],'combines',[[22,2],[11,2]],'receive',[[23,1],[4,1],[7,1]],'print',[[19,1]],'within',[[9,2],[6,4],[4,1],[22,1],[16,2],[23,2],[2,1],[14,2],[11,1],[12,1]],'devised',[[2,1]],'eyes',[[3,1]],'quit',[[5,1]],'exhaustive',[[13,1],[14,1]],'recordings',[[19,1],[22,1],[11,3],[5,1]],'bitwise',[[18,1]],'possible',[[6,11],[20,5],[22,6],[16,1],[17,1],[2,3],[9,2],[24,3],[10,2],[5,4],[19,2],[23,1],[14,9],[13,1],[12,2],[11,3]],'gigantic',[[20,1]],'footage',[[14,1],[5,1]],'displaying',[[3,1],[22,4],[24,1],[14,1],[15,3],[5,2]],'handy',[[12,2],[23,1],[2,1],[11,1],[5,3]],'feos',[[0,2]],'clearinputchanges',[[18,2]],'depends',[[22,5],[25,1],[10,1],[16,1],[9,2],[5,2]],'templates',[[3,1],[2,1]],'impede',[[6,1]],'solving',[[10,1],[7,2],[14,1],[12,1],[6,1]],'functional',[[11,2]],'unboundedness',[[14,1]],'unfeasible',[[20,2],[23,1]],'mental',[[16,1],[2,1]],'affect',[[22,3],[4,2],[2,1],[16,1],[11,5]],'lag',[[22,30],[4,1],[15,3],[23,5],[17,7],[2,3],[14,8],[8,1],[11,16]],'action',[[12,1],[15,1],[7,1],[8,1],[9,1],[5,1]],'activities',[[2,1]],'unpauses',[[7,1]],'modes',[[23,1],[7,1]],'eraser',[[4,1]],'contact',[[10,1]],'shade',[[22,4],[11,1]],'consisting',[[22,1],[12,1]],'branch5',[[17,2]],'reference',[[4,1],[5,1],[23,1],[0,1],[13,2],[12,1],[11,1]],'remained',[[2,1]],'recalculate',[[12,1]],'tables',[[23,1]],'explains',[[1,1]],'animation',[[23,3],[6,1]],'indicating',[[25,1]],'intricacies',[[8,1],[10,1]],'wearing',[[20,1]],'maximum',[[5,3],[12,1],[22,7],[14,2],[11,7],[6,2]],'binary',[[12,3],[25,5]],'2005',[[22,1]],'programmer',[[14,1]],'napkin',[[22,1]],'technique',[[8,1]],'trying',[[22,1],[10,1],[7,1],[2,1],[11,1]],'done',[[22,10],[18,8],[15,3],[23,1],[17,1],[19,2],[7,2],[2,1],[8,2],[11,6],[12,1]],'intend',[[6,1]],'exempts',[[14,1]],'importing',[[3,1],[22,1]],'gameplay',[[6,3],[4,1],[2,4],[7,1],[5,2]],'paid',[[6,1],[2,1]],'getting',[[12,1]],'bit',[[22,1],[24,2],[18,22],[7,1],[9,2],[25,20]],'encouraged',[[24,1],[10,1]],'publish',[[12,3],[2,1]],'analog',[[14,1],[22,3],[5,7]],'sessions',[[6,1]],'tyres',[[20,1]],'seeing',[[0,1],[10,1],[7,2],[9,1],[5,1]],'undefined',[[17,3]],'explanations',[[19,1]],'branch',[[22,13],[24,1],[18,1],[15,5],[5,4],[17,8],[23,2],[7,1],[14,3],[11,10]],'conventional',[[1,1],[6,1]],'astounding',[[7,1]],'basic',[[22,2],[7,2],[14,1],[21,1],[6,2]],'statement',[[7,1],[6,1]],'diversify',[[12,1]],'solved',[[12,1],[14,1]],'module',[[25,6]],'editor',[[22,10],[18,53],[21,3],[15,9],[17,11],[2,7],[8,1],[3,4],[24,5],[4,2],[25,2],[5,4],[19,3],[0,6],[23,21],[14,2],[1,1],[7,1],[12,6],[11,6]],'element',[[22,1],[24,2],[4,1],[15,1],[5,1]],'subsequent',[[22,2],[7,1]],'emancipates',[[2,1]],'multi',[[22,2],[14,2]],'treated',[[18,1]],'cannot',[[24,1],[25,1],[18,1],[20,1],[15,1]],'disadvantageous',[[6,1]],'rectangle',[[22,1],[12,1]],'perhaps',[[22,1]],'association',[[22,1],[9,2],[10,2]],'took',[[22,1],[2,1]],'imitates',[[11,1]],'plain',[[25,1]],'seem',[[7,2],[14,1],[9,1],[6,2]],'resumption',[[4,1]],'assigning',[[14,1]],'outsider',[[7,1],[2,1]],'accessible',[[11,1]],'tenfold',[[5,1]],'waiting',[[22,1],[14,2],[11,1],[5,1]],'setting',[[22,6],[4,3],[15,3],[5,2],[23,5],[11,3],[6,3]],'error',[[24,3],[14,1],[25,1],[23,12]],'radiobutton',[[22,2],[11,1]],'ram',[[3,1],[6,2],[20,1],[22,4],[15,2],[23,3],[14,1],[12,5],[11,1]],'analysis',[[3,1],[2,2],[14,1],[16,1],[9,1],[12,1]],'harder',[[2,2]],'labeled',[[16,1],[5,1]],'how',[[6,8],[22,3],[18,1],[2,4],[8,2],[9,2],[4,1],[10,1],[5,5],[19,5],[7,3],[11,4],[12,6]],'sounding',[[5,1]],'texts',[[22,1],[23,1],[6,1]],'hint',[[12,1]],'word',[[3,1],[5,1],[17,1],[25,1],[12,6],[6,1]],'fm2s',[[25,1]],'see',[[6,8],[20,1],[22,17],[16,9],[15,6],[2,3],[8,3],[9,5],[4,5],[10,3],[5,12],[19,2],[23,2],[14,4],[7,5],[11,5],[12,3]],'finding',[[22,1],[16,2],[23,1],[14,1],[2,1],[20,2],[6,4]],'units',[[14,1]],'minute',[[11,2],[9,1],[6,1]],'staying',[[2,1]],'tasedit',[[22,1],[23,2]],'alt',[[22,8],[24,1],[16,1],[15,8],[23,1],[17,5],[12,4],[11,1]],'crash',[[24,1]],'extremely',[[7,1],[9,1],[6,1]],'obstructing',[[11,1]],'isolated',[[19,1]],'possibility',[[22,1],[10,1],[12,1],[9,2]],'initially',[[6,1]],'testing',[[17,2],[0,1],[14,1],[8,1],[20,1],[6,3]],'are',[[6,18],[14,16],[18,4],[20,12],[22,74],[16,2],[15,12],[17,11],[2,7],[8,9],[9,11],[3,3],[24,8],[4,17],[10,4],[25,17],[5,20],[19,8],[23,2],[7,15],[1,1],[13,1],[11,21],[12,29]],'game',[[6,36],[20,11],[22,26],[16,3],[15,4],[2,26],[8,13],[9,14],[3,3],[4,13],[10,15],[25,1],[5,23],[19,1],[23,4],[14,40],[7,16],[11,13],[12,15]],'unsaved',[[3,1],[23,2],[24,1],[11,1],[12,1]],'press',[[6,4],[22,10],[16,15],[15,6],[17,18],[2,1],[8,2],[9,5],[24,1],[4,5],[10,5],[5,12],[19,1],[7,1],[11,18],[12,8]],'simulating',[[4,1]],'scalable',[[23,1]],'kills',[[2,2]],'decide',[[4,1],[8,1],[11,2],[20,2]],'discovered',[[14,1]],'typically',[[22,1]],'fonts',[[23,1]],'bookmarked',[[15,6],[16,3],[22,14],[8,1],[11,4],[5,4]],'paranoid',[[8,1]],'usb',[[11,1],[5,1]],'last',[[22,15],[6,3],[16,1],[15,4],[8,1],[9,2],[24,1],[4,2],[10,2],[25,2],[5,4],[23,6],[7,1],[11,5],[12,1]],'hurry',[[9,2],[6,1]],'losses',[[6,2]],'marioheight',[[12,3]],'mindset',[[6,1]],'situations',[[12,2],[20,1],[22,2],[7,1],[11,1],[6,1]],'inexactitude',[[19,1]],'varies',[[6,1]],'consolidate',[[4,1],[11,1]],'dependencies',[[14,1],[6,1]],'starting',[[22,5],[18,1],[16,1],[15,2],[17,2],[9,1],[3,1],[24,1],[4,1],[10,1],[5,3],[7,2],[14,2],[11,2]],'reason',[[22,1],[2,2]],'arrays',[[20,2]],'virtual',[[17,4],[22,18],[23,6],[2,1],[15,3],[11,7]],'superimposing',[[8,1]],'inputlog',[[23,6]],'alternating',[[9,1],[22,1],[10,1],[5,1],[17,1],[11,1],[12,1]],'forum',[[19,1],[22,1]],'into',[[6,14],[20,4],[22,11],[16,1],[15,3],[21,1],[17,7],[2,2],[8,4],[9,4],[3,1],[24,3],[4,3],[10,3],[25,3],[5,7],[19,3],[23,6],[14,4],[7,5],[11,5],[12,5]],'replacement',[[22,1],[14,1]],'scrolls',[[22,2],[16,4],[11,3],[23,2]],'slightly',[[5,1],[22,1],[8,1],[6,1]],'replaced',[[22,2],[24,1],[4,1],[5,1],[7,1],[14,1],[12,1],[11,1]],'discrepancy',[[14,1],[19,1],[5,1]],'sstart',[[25,1]],'multiple',[[5,2],[22,4],[2,1]],'located',[[22,3],[4,3],[10,1],[18,1],[16,1],[5,4],[7,1],[12,1],[20,3]],'success',[[25,1],[7,1],[20,1],[6,1]],'splicer',[[22,1],[23,2],[5,5]],'resembling',[[12,1]],'strives',[[14,1]],'matching',[[22,1]],'hierarchical',[[22,1]],'cells',[[22,25],[4,4],[15,2],[11,1]],'comparing',[[20,12],[22,2],[23,3],[8,2],[11,1],[6,1]],'bots',[[11,1],[14,5]],'registration',[[22,1]],'hiding',[[22,1]],'helping',[[11,1],[5,1]],'console',[[3,1],[22,2],[14,2],[12,3],[15,1]],'estimate',[[22,3],[8,1],[5,2]],'stream',[[6,1],[2,2],[7,1],[25,8],[5,1]],'transformation',[[2,2]],'history',[[20,1],[22,43],[18,2],[16,3],[15,8],[17,4],[2,1],[8,1],[9,4],[10,1],[25,6],[5,7],[23,10],[7,1],[12,7],[11,11]],'inventiveness',[[6,2]],'stuck',[[6,1]],'delays',[[14,1]],'enables',[[11,1]],'supporting',[[22,2],[24,1]],'rightclicks',[[24,1]],'what',[[19,1],[4,1],[8,1],[12,1],[6,1]],'consider',[[6,4],[12,1],[10,2],[7,2],[8,1],[11,1],[9,1]],'set',[[6,6],[22,25],[18,4],[16,6],[15,12],[17,10],[2,2],[9,2],[24,3],[4,12],[10,3],[25,1],[5,15],[19,2],[23,5],[7,1],[14,2],[11,17],[12,4]],'writers',[[6,1]],'raw',[[22,1],[2,1]],'reloading',[[7,1]],'height',[[22,9],[9,1],[2,1]],'parts',[[3,1],[4,1],[15,1],[25,1],[7,1],[14,1],[12,1],[6,5]],'flash',[[22,1],[4,1],[7,1],[10,2],[9,1],[5,1]],'promptly',[[20,1]],'macro1',[[22,1]],'framework',[[3,1],[20,1]],'because',[[6,14],[20,1],[22,17],[15,1],[17,1],[2,6],[8,4],[9,4],[24,3],[4,8],[10,5],[25,2],[5,8],[19,1],[23,3],[14,2],[7,10],[11,10],[12,4]],'decisive',[[10,1],[7,3]],'open',[[3,3],[6,2],[22,1],[24,6],[16,1],[15,12],[21,1],[17,1],[14,1],[1,1],[12,7],[11,5]],'decompose',[[14,1]],'methodicalness',[[6,1]],'methodically',[[14,1]],'digits',[[22,2],[5,1]],'timing',[[25,1],[23,1]],'period',[[23,1],[14,1],[11,3],[6,1]],'waste',[[23,1],[2,1]],'nevertheless',[[2,1]],'nes',[[12,1],[19,1],[22,2],[24,5],[15,5],[11,3]],'modal',[[22,1]],'message',[[24,3],[25,1],[5,2],[17,2],[19,1],[12,1],[11,1]],'cocktail',[[2,1]],'available',[[22,1],[24,1],[18,1],[7,1],[12,2],[5,3]],'activated',[[10,1],[12,1]],'accounts',[[11,1]],'vulnerabilities',[[2,1]],'clearselection',[[24,1]],'hash',[[25,1]],'paused',[[22,3],[18,3],[15,2],[17,1],[2,1],[8,1],[3,1],[24,1],[4,1],[5,2],[23,2],[7,2],[11,1],[12,1]],'transforming',[[24,1]],'select',[[22,8],[4,6],[18,2],[16,2],[15,8],[23,3],[17,23],[25,3],[12,4],[11,5]],'usual',[[19,2],[23,1],[25,1],[2,1],[15,1],[5,1]],'common',[[12,1],[23,2]],'imagination',[[2,1]],'logging',[[22,3],[2,1]],'support',[[22,2],[14,1],[12,1],[23,2]],'considers',[[22,2]],'sorry',[[6,1]],'folder',[[18,2],[11,1],[12,1]],'occupies',[[11,1],[6,1]],'suited',[[12,1]],'positioning',[[10,1]],'without',[[22,10],[6,2],[16,1],[15,1],[2,3],[8,6],[9,2],[24,2],[5,3],[23,1],[14,4],[7,3],[11,6],[12,8]],'awareness',[[4,1]],'pretty',[[20,1],[12,2],[2,1]],'address',[[14,1],[12,2],[6,1]],'groundwork',[[2,1]],'concentration',[[6,1]],'requires',[[6,1],[22,1],[10,1],[2,1],[14,1],[8,1],[12,2],[11,1]],'0xce',[[12,2]],'sequential',[[23,1]],'realizing',[[7,1]],'rolling',[[19,1],[22,3],[24,3],[16,2],[9,1]],'alpha',[[22,3]],'aggregate',[[20,1]],'distributed',[[8,1],[21,1],[14,1]],'often',[[6,6],[20,1],[18,1],[16,1],[17,7],[2,1],[8,2],[9,2],[24,3],[4,2],[10,2],[5,2],[19,1],[14,1],[7,6],[11,1],[12,3]],'connect',[[22,1],[5,2]],'evolution',[[22,1],[5,1]],'gui',[[12,1],[23,6],[18,3],[24,3],[15,2],[11,2]],'entitled',[[12,1]],'low',[[4,1],[6,1]],'encoded',[[12,2]],'feature',[[22,9],[4,3],[18,1],[15,2],[5,2],[19,1],[23,2],[14,3],[8,1],[12,3],[11,10]],'differences',[[22,1]],'gradients',[[23,1]],'horizontal',[[22,2],[15,1],[6,1]],'discarding',[[8,1]],'terminology',[[22,1]],'sensible',[[12,1]],'answers',[[13,1]],'demand',[[22,1],[23,10]],'duration',[[6,1],[10,2],[2,1]],'formulate',[[2,1]],'conclude',[[22,1]],'nullifies',[[9,1]],'unique',[[25,1],[2,1],[12,5],[6,1]],'care',[[20,1],[10,1],[11,1]],'displays',[[3,1],[22,16],[4,2],[10,1],[24,1],[5,3],[23,3],[14,2],[11,2]],'code',[[22,2],[18,1],[21,5],[15,1],[23,9],[19,3],[25,3],[14,2],[2,5],[12,10]],'believed',[[22,1]],'analogy',[[22,1],[20,3],[5,1]],'abstract',[[22,1],[10,1],[7,1],[2,1],[13,1],[12,1]],'bit1',[[25,2]],'|commands|port0|port1|port2|',[[25,1]],'processing',[[14,2]],'hesitate',[[2,1]],'fast',[[9,1],[6,2],[20,1],[16,1],[5,3],[14,1],[11,1],[12,1]],'improves',[[22,1],[6,1]],'senses',[[6,1]],'org',[[6,1],[12,1],[2,1]],'loses',[[23,1]],'for',[[22,96],[11,52],[18,6],[12,50],[15,17],[2,9],[8,28],[9,14],[3,5],[25,9],[7,12],[13,1],[16,6],[21,1],[17,2],[24,11],[4,14],[10,14],[5,24],[19,7],[0,1],[23,44],[14,38],[20,13],[6,30]],'bumping',[[9,1]],'even',[[6,21],[22,15],[18,4],[2,5],[8,4],[9,3],[3,1],[24,4],[4,2],[10,6],[5,4],[19,1],[23,1],[14,3],[7,9],[11,7],[12,5]],'invulnerability',[[12,1]],'revolutionary',[[7,3]],'reached',[[6,1],[22,2],[2,1]],'blindly',[[22,1],[9,1]],'tradition',[[22,1]],'throughout',[[13,1],[16,1],[14,1]],'swap',[[17,3],[22,1]],'experimenting',[[7,1]],'battletoads',[[17,1]],'waves',[[6,1]],'resulting',[[7,1],[14,1],[11,1],[5,2]],' build',[[14,1]],'cold',[[11,1]],'jumping',[[6,4],[22,6],[4,1],[24,1],[16,20],[15,1],[5,1],[23,3],[7,1],[12,3],[11,2]],'comfortable',[[6,2],[23,1],[2,1]],'4th',[[22,1],[10,1],[25,1]],'500',[[11,1]],'informs',[[24,1],[4,1]],'adjust',[[3,2],[12,1],[10,1],[23,1],[2,1],[8,1],[11,3],[6,2]],'powerful',[[24,2],[5,1]],'configuration',[[24,1],[11,1]],'makes',[[9,3],[12,1],[22,3],[5,1],[23,3],[2,1],[7,6],[11,1],[6,4]],'rarely',[[22,1],[15,1],[5,1],[17,16],[7,2],[12,1],[11,1]],'enemy',[[8,3],[9,7],[6,4]],'study',[[3,1],[0,1]],'blue',[[22,18],[24,1],[4,12],[10,1],[16,1],[15,1],[5,18],[14,3],[8,1],[11,3]],'precisely',[[19,1],[24,1],[8,1],[12,1],[23,1]],'newbies',[[11,1]],'filename',[[17,1],[19,1],[11,2],[23,4]],'marioy',[[12,3]],'hardware',[[19,1],[22,1],[18,1],[14,1],[15,2],[23,2]],'boundary',[[22,4],[11,1],[6,1]],'arriving',[[7,1]],'greenzoned',[[22,2]],'recognition',[[9,1]],'usually',[[6,11],[20,1],[22,6],[16,1],[15,1],[2,1],[8,3],[9,3],[24,1],[4,2],[10,1],[25,2],[5,3],[19,2],[14,6],[7,7],[11,7],[12,8]],'clone',[[17,6],[15,2],[5,2]],'sometimes',[[11,1],[12,1],[4,1],[16,1],[5,1],[19,2],[7,6],[14,2],[8,1],[9,1],[6,8]],'limits',[[23,1],[0,1],[2,1],[14,2],[6,2]],'approve',[[24,1]],'elaborate',[[7,1]],'1440',[[11,1]],'form',[[22,2],[4,1],[10,1],[25,2],[23,1],[14,5],[1,1],[8,1],[12,3],[20,1]],'hottest',[[4,1]],'part',[[6,6],[22,4],[16,1],[2,2],[9,1],[3,1],[4,4],[5,5],[19,1],[14,1],[1,1],[7,1],[11,3],[12,4]],'recover',[[11,1]],'submissions',[[12,1]],'active',[[22,1],[24,1],[4,1]],'automatic',[[22,6],[10,1],[12,2],[11,1]],'plan',[[22,1],[20,1],[6,1]],'learned',[[20,1]],'getplaybacktarget',[[18,2]],'synchronized',[[22,1]],'type',[[9,1],[6,1],[4,2],[20,1],[22,5],[25,3],[5,3],[17,3],[19,1],[23,3],[11,2],[12,1]],'unambiguous',[[7,1]],'lacks',[[22,1]],'21060',[[25,1]],'describe',[[12,2],[2,1]],'debugger',[[15,1]],'wheel',[[22,7],[16,9],[15,16],[9,2],[24,7],[4,4],[10,2],[5,7],[19,2],[23,2],[7,1],[12,1],[11,1]],'judging',[[20,1],[6,1]],'free',[[22,2],[15,1],[2,1],[8,1],[9,1],[10,2],[25,1],[23,1],[19,1],[0,1],[14,1],[12,1],[11,2]],'lovingly',[[12,1]],'20fps',[[18,1]],'methods',[[22,3],[5,1],[2,2],[1,2],[7,4],[11,1],[6,1]],'limitation',[[22,1],[16,1]],'research',[[14,2],[23,1],[6,2]],'axis',[[22,1]],'deal',[[10,1],[6,1]],'represents',[[14,1]],'resembles',[[0,1],[8,1]],'pulled',[[24,1]],'concepts',[[6,1]],'types',[[17,1],[22,1],[25,3],[7,1],[20,2],[23,1]],'ipad',[[17,1]],'spend',[[10,2],[7,2],[14,1],[9,1],[12,1]],'50000',[[11,1]],'unpacks',[[22,1]],'update',[[23,2],[4,1],[14,1]],'simulate',[[22,1],[24,1]],'polls',[[22,1]],'disk',[[22,4],[24,5],[18,1],[15,11],[5,1],[25,6],[12,3],[11,5]],'submission',[[12,1],[6,2]],'intact',[[19,1],[22,2],[11,1]],'gameresources',[[12,1]],'interaction',[[24,1],[10,1],[2,1],[14,2],[8,1],[9,1]],'unused',[[14,2],[8,1],[7,1]],'aren',[[5,1],[12,1],[14,1],[8,1],[11,2],[6,2]],'kind',[[4,1],[2,1],[7,1],[8,1],[6,2]],'checking',[[22,1],[18,1],[14,1],[23,2]],'disregarding',[[5,1]],'musical',[[8,1]],'imitating',[[11,1]],'with',[[22,73],[11,30],[18,6],[6,31],[15,14],[2,13],[8,12],[9,20],[3,4],[25,9],[7,8],[1,1],[13,3],[16,10],[21,3],[17,10],[24,17],[4,20],[10,9],[5,27],[19,5],[0,1],[23,10],[14,11],[12,22],[20,6]],'arbitrary',[[2,2]],'want',[[6,1],[22,1],[18,1],[16,6],[15,1],[2,1],[8,2],[9,2],[4,1],[10,1],[5,4],[19,1],[7,2],[11,6],[12,5]],'checkpoints',[[6,1]],'rough',[[10,1],[4,1],[14,1],[9,1]],'ways',[[22,2],[16,2],[15,1],[2,2],[8,1],[9,3],[3,1],[4,3],[14,5],[13,1],[7,1],[12,1],[6,2]],'lighter',[[22,1]],'000001',[[22,1]],'reside',[[23,1]],'rushing',[[20,1]],'topmost',[[22,1]],'stored',[[11,4],[22,14],[18,1],[25,3],[5,1],[17,2],[23,4],[20,4],[12,6]],'resume',[[24,2],[4,1],[7,1],[5,2]],'appending',[[22,1],[15,1],[14,1]],'speedruns',[[22,1],[20,2],[14,2]],'reverses',[[18,1]],'character',[[12,1],[22,1],[4,1],[25,1],[5,3],[2,3],[7,1],[9,1],[6,5]],'calculated',[[22,1]],'alternative',[[6,1],[22,4],[16,2],[15,1],[2,1],[8,1],[9,1],[24,1],[4,1],[5,6],[23,1],[14,1],[7,3],[11,2],[20,1]],'specifies',[[11,1]],'ebook',[[5,1]],'rename',[[17,6]],'tells',[[24,1]],'goes',[[6,1],[22,7],[4,1],[2,1],[20,3],[5,2]],'ids',[[17,1],[23,5]],'output',[[3,1],[11,3],[22,12],[5,1],[23,1],[14,10],[12,2],[20,1]],'1st',[[5,1],[22,3],[7,1],[25,3],[6,4]],'kick',[[23,1]],'passes',[[22,1]],'tangible',[[7,1]],'si_none',[[25,4]],'prepares',[[22,1]],'necessity',[[6,1],[2,1]],'knowing',[[16,1],[10,1],[23,1]],'engaging',[[10,1]],'defeating',[[6,1]],'refresh',[[4,1],[2,1]],'confirming',[[20,1]],'immediately',[[22,5],[4,1],[10,2],[16,5],[15,1],[5,1],[23,1],[2,1],[7,3],[8,1],[9,4],[6,2]],'fractional',[[14,1]],'leftmost',[[16,1],[11,1]],'drag',[[22,5],[24,2],[4,2],[16,2],[15,4],[23,1],[17,6],[7,1],[9,1],[11,2]],'epub',[[17,1],[24,1],[18,1],[14,1],[23,1]],'linearity',[[2,1]],'extend',[[12,1]],'copied',[[17,1],[19,1],[22,3],[16,1],[15,1],[5,2]],'faster',[[14,1],[20,3],[10,1],[22,1],[15,2],[23,1],[7,2],[2,2],[8,1],[12,1],[6,2]],'interactivity',[[5,1]],'openness',[[2,1]],'obviously',[[8,1],[4,1],[12,2]],'000020',[[22,1]],'unpredictable',[[14,1]],'route',[[5,1]],'below',[[5,4],[22,1],[16,2],[15,2],[9,1]],'refer',[[18,1],[20,1]],'redesigned',[[22,2]],'should',[[6,9],[20,2],[18,1],[22,13],[16,1],[17,2],[2,2],[8,2],[9,4],[4,2],[10,3],[25,2],[5,3],[19,3],[23,24],[14,1],[7,2],[11,7],[12,7]],'allows',[[22,8],[16,3],[15,3],[21,1],[2,3],[8,2],[9,1],[3,1],[24,1],[4,1],[10,2],[5,8],[14,4],[11,5],[6,3]],'situation',[[6,1],[20,1],[16,1],[19,1],[7,1],[2,1],[8,2],[12,3],[9,4]],'reverted',[[17,1],[4,2]],'attributes',[[22,3]],'manipulations',[[14,1],[2,1]],'resize',[[15,1]],'intersection',[[22,1]],'experimental',[[22,1],[23,1],[4,1],[5,1]],'sent',[[22,4],[24,2],[14,1],[7,2]],'allotted',[[14,1],[8,1],[5,1]],'undoing',[[22,1],[9,1]],'sequences',[[15,1],[22,3],[7,1],[12,5],[6,1]],'determined',[[22,1],[14,1],[2,1],[25,1]],'aid',[[6,1],[2,1]],'rotated',[[24,1]],'technically',[[8,1],[9,2]],'truncating',[[22,3],[23,3]],'crossing',[[22,4],[16,2],[15,3]],'wm_mousewheel',[[23,1]],'between',[[6,9],[20,1],[22,13],[15,3],[2,2],[8,2],[9,3],[3,1],[24,2],[4,2],[10,3],[5,7],[19,1],[23,9],[14,7],[7,6],[11,3],[12,2]],'delete',[[24,1],[18,1],[15,4],[5,6],[17,7],[14,1],[11,1],[6,1]],'motor',[[8,1]],'skipping',[[14,1]],'typical',[[15,1],[23,1],[2,1],[13,1],[12,3],[6,1]],'mario',[[12,3],[4,3],[10,2],[5,1],[7,1],[14,1],[8,1],[9,2],[6,16]],'impartiality',[[10,1]],'implementation',[[24,1],[0,1],[7,1],[21,2],[23,2]],'unimportant',[[14,1]],'won',[[6,4],[20,1],[18,3],[17,1],[2,2],[9,1],[3,1],[24,2],[4,2],[5,4],[19,2],[7,2],[11,8],[12,3]],'formalize',[[14,1],[6,1]],'whether',[[22,5],[4,1],[2,1],[11,1],[5,1]],'simplifies',[[7,1],[11,1],[5,1]],'music',[[0,1],[4,1],[14,1]],'rom',[[3,2],[15,1],[24,10],[25,1],[11,5],[12,1]],'cope',[[6,1]],'guide',[[3,2],[4,1],[10,1],[19,1],[0,1],[2,2],[1,2],[14,1],[12,1],[6,1]],'tune',[[19,1],[5,1]],'ideal',[[7,1],[6,2]],'evaluate',[[22,1],[20,2],[5,1]],'achievement',[[5,1]],'motions',[[11,1]],'emptiness',[[16,1],[15,1]],'visually',[[22,3],[20,1],[6,1]],'cheat',[[12,1]],'calculate',[[11,1],[6,1]],'bullets',[[6,1]],'currently',[[22,8],[24,3],[4,1],[18,4],[16,8],[15,5],[5,2],[17,2],[23,1],[14,1]],'postpone',[[20,1],[11,1],[6,1]],'reflected',[[4,1]],'higher',[[4,1],[2,1],[7,1],[20,1],[6,1]],'fade',[[23,1]],'submitdeleteframes',[[17,1],[22,1],[18,2]],'structuring',[[4,1],[6,1]],'formatted',[[12,1]],'intervals',[[22,2],[12,1],[6,3]],'both',[[6,4],[20,1],[22,6],[17,1],[2,2],[9,1],[24,1],[4,4],[10,1],[5,2],[19,2],[0,1],[7,5],[1,1],[11,4],[12,3]],'redone',[[2,1]],'miscellaneous',[[25,1]],'rerecording',[[24,1],[14,1],[2,1],[23,1]],'check',[[22,2],[18,1],[21,1],[15,3],[9,1],[3,1],[25,1],[5,1],[19,1],[23,1],[7,1],[11,1],[12,1]],'doing',[[6,1],[24,1],[20,1],[11,1]],'awkward',[[22,1]],'freeing',[[22,1]],'big',[[6,1],[14,1],[12,1],[11,1]],'associates',[[2,1]],'custom',[[14,2],[12,1],[2,2]],'abstraction',[[4,1]],'frame#',[[17,3],[22,1],[4,1],[24,1],[15,2]],'important',[[9,1],[6,1],[20,3],[5,1],[19,1],[7,2],[14,1],[11,1],[12,2]],'activity',[[10,2],[7,1],[14,1],[8,1],[9,1],[20,1]],'reappear',[[11,1]],'drawn',[[22,2],[4,1],[12,2],[11,1]],'seriously',[[8,1]],'mashing',[[5,1]],'welcome',[[0,1]],'attaches',[[11,1]],'mod',[[14,1]],'rerecordcount',[[25,1]],'amount',[[22,1],[16,3],[5,2],[7,1],[2,1],[14,3],[12,1],[11,4]],'gamepads',[[17,3],[25,1],[5,2]],'systematic',[[12,3],[5,1]],'meditate',[[10,1]],'link',[[3,1]],'taking',[[14,1]],'application',[[20,1],[5,1]],'binding',[[11,2],[2,1]],'wip1',[[17,1]],'unsigned',[[25,3]],'sat',[[5,1]],'assisted',[[20,1],[14,2]],'fantasy',[[2,1]],'final',[[22,4],[10,1],[21,1],[5,1],[7,2],[14,1],[20,1],[6,8]],'uniqueness',[[12,1]],'creation',[[3,1],[22,6],[21,1],[15,1],[23,5],[17,1],[9,1],[12,1]],'define',[[10,1],[8,1],[9,1],[6,2]],'granted',[[9,2],[22,1],[5,1],[17,3],[2,1],[8,1],[12,1],[6,1]],'chosen',[[12,2],[22,1],[4,3],[21,1],[5,3],[17,2],[7,1],[8,1],[11,1],[6,5]],'choice',[[11,1],[20,1]],'startup',[[22,1]],' microphone',[[24,1]],'lists',[[22,1],[24,1]],'16th',[[12,2]],'build',[[10,1],[23,1]],'resets',[[23,1],[6,1]],'status',[[23,2],[15,1],[18,1]],'was',[[6,5],[20,1],[18,3],[22,16],[16,2],[15,6],[21,1],[17,18],[2,6],[9,3],[24,3],[4,5],[10,4],[25,9],[5,10],[19,3],[23,7],[7,1],[14,3],[11,3],[12,4]],'polished',[[12,1],[6,1]],'flashes',[[17,2],[22,1],[23,2],[11,1],[5,2]],'air',[[6,1]],'progression',[[14,1]],'agrees',[[23,1]],'selected',[[22,33],[24,1],[4,9],[18,3],[15,19],[5,7],[17,8],[19,3],[23,5],[14,2],[12,6],[11,4]],'temporal',[[5,2]],'brings',[[24,1],[9,1],[11,2]],'flow',[[3,1],[11,1],[2,4],[7,2],[9,1],[6,3]],'overview',[[1,1]],'combinations',[[3,1],[5,2],[15,2],[22,2],[12,1],[6,1]],'html',[[19,1],[1,1],[21,1],[9,1],[12,1]],'laglog',[[23,5]],'prematurely',[[8,1],[10,1]],'everything',[[3,1],[22,2],[10,1],[2,1],[7,1],[12,1],[6,1]],'clears',[[23,3],[18,2],[5,2]],'stumbled',[[6,1]],'destination',[[12,1],[7,2]],'fceultra',[[21,1]],'use',[[6,4],[20,4],[18,5],[22,7],[16,23],[15,5],[21,1],[2,3],[8,6],[9,3],[24,2],[4,4],[10,3],[5,9],[19,4],[23,1],[14,6],[1,1],[7,2],[11,17],[12,13]],'masterfully',[[2,1]],'visible',[[5,2],[22,5],[23,1],[16,2],[15,4],[6,1]],'selection',[[22,69],[18,2],[16,26],[15,29],[17,4],[2,1],[9,4],[24,6],[4,17],[25,5],[5,16],[23,18],[14,7],[11,4],[12,7]],'add',[[22,4],[6,1],[4,1],[5,1],[23,2],[12,1],[11,1]],'recipient',[[12,2]],'uncompressed',[[22,3],[23,1]],'considered',[[22,3],[24,2],[4,1],[10,1],[25,4],[7,1],[14,3],[20,4],[6,3]],'occurs',[[22,4],[7,1],[8,1],[20,1],[6,2]],'suboptimally',[[7,1]],'roll',[[20,2],[22,70],[16,28],[15,42],[17,17],[2,1],[8,1],[9,3],[3,3],[24,3],[4,22],[10,2],[25,4],[5,15],[19,5],[23,12],[14,16],[7,1],[12,8],[11,20]],'spirit',[[2,1]],'determine',[[22,4],[14,1]],'fatal',[[7,1],[8,1],[6,1]],'unpausing',[[10,1],[4,1],[9,1]],'0000005',[[4,1]],'completion',[[14,2]],'impossible',[[5,3],[2,1]],'roughness',[[6,1]],'highly',[[22,1],[12,1]],'acquire',[[2,1]],'defined',[[5,1],[22,1],[14,2],[20,2],[6,1]],'opposite',[[6,1]],'again',[[9,2],[6,1],[4,2],[22,4],[24,1],[5,3],[11,4],[12,1]],'bugs',[[14,5],[6,1]],'sides',[[6,1]],'they',[[6,8],[22,8],[15,3],[2,3],[8,2],[9,3],[3,2],[24,4],[4,8],[25,1],[5,7],[23,2],[14,2],[7,5],[11,6],[12,9]],'basically',[[19,1],[7,2],[11,1],[5,2]],'day',[[22,1],[11,1]],'activating',[[12,1]],'trace',[[12,1],[15,1]],'prefix',[[23,2]],'slip',[[6,1]],'regain',[[6,1]],'relationship',[[22,1]],'resources',[[23,16],[12,1],[6,1]],'logger',[[15,2]],'present',[[11,1],[6,1]],'run',[[3,1],[12,7],[10,1],[18,4],[22,2],[15,1],[5,2],[17,5],[23,4],[8,1],[9,1],[6,1]],'clear',[[22,1],[4,1],[18,3],[15,3],[5,2],[17,6],[25,1],[2,3]],'smooth',[[23,1],[7,1]],'explicit',[[7,1]],'usability',[[11,1]],'speeding',[[3,1],[14,3],[9,1],[20,1]],'during',[[22,15],[6,2],[18,4],[2,3],[8,1],[9,1],[3,2],[24,1],[4,2],[5,6],[14,2],[11,5],[12,7]],'interrupted',[[11,1]],'enforcing',[[2,1]],'obvious',[[10,1],[7,3],[2,1],[12,2],[6,6]],'graphical',[[22,1],[20,1],[5,1]],'unless',[[25,1],[11,3],[12,1]],'determinism',[[22,1],[14,1]],'ruler',[[5,1],[2,1]],'wise',[[7,1],[6,1]],'followed',[[6,1]],'tilt',[[22,1]],'life',[[14,1],[10,1],[7,1]],'complex',[[6,4],[20,3],[2,1],[7,1],[12,1],[5,2]],'input',[[6,16],[20,3],[18,19],[22,102],[16,4],[15,27],[17,68],[2,16],[8,21],[9,16],[3,2],[24,5],[4,17],[10,16],[25,16],[5,38],[19,11],[23,38],[7,45],[1,1],[14,43],[11,59],[12,34]],'particular',[[22,2],[23,1]],'minimal',[[12,1],[6,3]],'offered',[[12,1]],'conventions',[[2,1]],'text',[[6,5],[22,12],[18,1],[16,5],[15,8],[17,16],[8,1],[3,4],[4,3],[10,2],[25,11],[5,1],[23,6],[14,2],[12,12],[11,9]],'fork',[[5,1]],'passing',[[22,1],[12,1],[6,1]],'devices',[[25,3]],'minus',[[15,1]],'editing',[[6,4],[22,8],[18,1],[15,12],[2,3],[8,6],[9,4],[24,2],[4,4],[10,8],[25,1],[5,6],[19,1],[23,8],[14,6],[7,4],[11,7],[12,5]],'hitbox',[[12,2]],'such',[[6,20],[20,2],[18,6],[22,7],[15,1],[17,2],[2,3],[8,1],[9,2],[3,1],[24,5],[4,2],[10,2],[5,5],[19,1],[23,3],[14,2],[7,6],[11,5],[12,4]],'edges',[[3,1],[6,1]],'report',[[22,1]],'force',[[6,2]],'writes',[[22,1],[25,1],[23,1]],'performance',[[10,1],[11,1]],'efficiency',[[2,1]],'continually',[[7,1]],'separation',[[22,1]],'stopping',[[22,2],[9,1],[20,1]],'removing',[[22,4],[23,1],[4,2],[14,1],[11,1],[5,2]],'subdivision',[[6,2]],'serializes',[[25,1]],'bookmark4',[[17,1]],'pattern',[[3,2],[22,8],[15,3],[5,6],[17,10],[23,2],[25,1],[14,1],[12,15],[11,5]],'bright',[[19,1],[22,1],[4,2],[11,4]],'ins',[[5,1]],'breakthrough',[[7,1],[2,1]],'pick',[[6,1]],'member',[[15,1]],'theoretically',[[22,1],[14,1]],'heatmap',[[22,6]],'loading',[[22,10],[24,12],[25,5],[5,2],[17,1],[23,5],[7,4],[2,1],[8,2],[12,3],[11,5]],'affecting',[[6,1],[7,1],[5,1]],'stroke',[[17,1],[11,1],[5,1]],'fits',[[22,2],[7,1],[11,1],[6,1]],'numpad',[[11,1]],'bookmark0',[[17,1]],'construct',[[9,1],[6,1]],'stick',[[22,2],[10,1],[14,1],[16,1],[12,1],[5,1]],'load',[[22,2],[6,1],[15,13],[17,2],[8,2],[3,1],[24,11],[25,3],[5,3],[23,2],[7,4],[12,1],[11,10]],'trap',[[6,1]],'synchronize',[[12,1]],'organism',[[2,1]],'applications',[[15,2],[7,1]],'prevent',[[3,1],[24,1],[12,1],[5,2]],'tracks',[[23,3]],'2011',[[22,2],[11,1],[18,1],[6,1],[15,1],[2,1],[8,1],[9,1],[3,1],[25,1],[7,1],[1,1],[13,1],[16,1],[21,1],[17,1],[24,1],[4,1],[10,1],[5,1],[19,1],[0,1],[23,1],[14,1],[12,1],[20,1]],'combine',[[5,2],[19,1],[11,1],[9,1]],'inferior',[[8,1]],'zapper',[[25,4]],'themselves',[[8,1],[11,1],[2,1]],'restored',[[3,1],[22,2],[11,1]],'diverse',[[20,1]],'parents',[[22,2]],'tas',[[12,11],[22,14],[18,53],[21,3],[15,8],[17,11],[2,10],[8,1],[9,2],[3,7],[24,5],[4,3],[10,1],[25,2],[5,4],[19,4],[0,5],[23,18],[7,3],[1,1],[14,9],[11,8],[6,10]],'dropped',[[9,1]],'encouraging',[[2,1]],'operations',[[3,1],[22,12],[4,1],[18,1],[15,3],[5,3],[17,3],[0,1],[23,11],[14,1],[13,2],[11,3]],'hollow',[[11,2]],'average',[[16,1]],'little',[[20,1],[22,1],[4,1],[2,1],[12,2],[6,1]],'necessary',[[6,2],[22,13],[16,1],[2,1],[8,5],[9,3],[24,2],[4,1],[10,3],[5,3],[19,1],[23,3],[14,3],[7,3],[11,5],[12,3]],'checks',[[22,1],[23,4],[14,1]],'outran',[[9,1]],'position',[[22,15],[11,3],[18,2],[16,3],[15,4],[17,1],[9,4],[3,1],[24,2],[10,2],[25,6],[5,8],[23,3],[12,5],[6,1]],'vision',[[1,1],[22,1],[23,1]],'linear',[[5,2],[12,1],[2,2]],'accessory',[[2,1]],'train',[[8,1]],'generating',[[12,1],[23,1]],'350',[[6,2]],'comma',[[15,1]],'gaining',[[8,1]],'clipboard',[[22,3],[16,3],[15,5],[5,7],[17,6],[23,5],[12,3]],'aborted',[[11,1]],'relying',[[9,1]],'now',[[22,5],[6,6],[2,5],[8,1],[9,4],[3,2],[4,2],[10,2],[25,1],[5,9],[7,5],[11,7],[12,3]],'sensitive',[[22,1]],'built',[[22,1],[14,1],[21,1],[12,1],[5,1]],'further',[[22,2],[24,1],[10,1],[2,1],[11,1],[6,1]],'dark',[[22,2],[4,3],[14,1],[5,1]],'insert#',[[17,2]],'depths',[[9,1]],'availability',[[22,1]],'appreciate',[[6,1]],'marks',[[22,2],[4,1],[14,2]],'itself',[[5,1],[22,2],[11,2],[6,1]],'away',[[22,2],[24,1],[10,1],[16,1],[15,1],[5,1],[19,1],[2,2],[7,2],[8,2],[9,1],[6,10]],'reaction',[[2,2]],'youtube',[[12,1],[14,1]],'became',[[14,1],[23,1],[5,1]],'imperfect',[[6,4]],'callback',[[18,10]],'working',[[6,6],[20,3],[2,2],[9,2],[24,1],[4,2],[10,2],[25,1],[5,6],[19,1],[23,14],[14,1],[1,1],[7,1],[11,3],[12,2]],'systematizes',[[19,1]],'intense',[[6,2],[11,1],[2,1]],'involving',[[22,2],[12,1]],'exists',[[22,1],[24,1],[4,2],[11,1]],'ans',[[22,1],[11,1],[18,1],[6,1],[15,1],[2,1],[8,1],[9,1],[3,1],[25,2],[7,1],[1,1],[13,1],[16,1],[21,1],[17,1],[24,1],[4,1],[10,1],[5,1],[19,1],[0,4],[23,1],[14,1],[12,1],[20,1]],'unselected',[[22,2],[15,1]],'intercepts',[[23,1]],'rewind',[[4,1],[16,2],[15,2],[5,4],[19,1],[14,1],[11,3],[9,3]],'corrupted',[[24,2]],'somehow',[[7,1]],'placed',[[17,1],[22,1],[14,1],[15,1],[11,1]],'finishes',[[12,1],[23,1]],'patterns',[[3,1],[22,7],[24,3],[15,1],[5,1],[23,3],[2,2],[14,1],[12,14],[11,2]],'decision',[[23,2],[10,3],[6,1]],'true',[[22,2],[18,2],[14,1],[2,1],[25,6]],'reread',[[10,1],[12,1]],'row',[[22,3],[4,3],[10,1],[18,1],[15,9],[5,1],[17,3],[23,1],[14,6],[8,1]],'quiet',[[6,1]],'distinction',[[7,1]],'checkbox',[[9,3],[22,5],[10,2],[18,2],[24,2],[16,1],[15,3],[5,13],[17,2],[8,1],[11,4],[12,5]],'turn',[[11,2],[22,1],[8,1],[9,1],[5,2]],'treat',[[5,1]],'api',[[22,2],[0,1],[18,2],[14,1],[13,1],[21,1]],'easier',[[11,2],[22,1],[5,3],[23,1],[2,3],[8,1],[12,3],[6,3]],'restore',[[12,2],[22,5],[4,1],[10,3],[15,10],[5,3],[19,1],[23,1],[7,1],[8,1],[9,5],[11,3]],'properly',[[9,1],[5,1]],'naturally',[[20,1],[12,1],[6,2]],'food',[[8,1]],'differs',[[17,2],[22,1],[24,1],[5,1]],'timestamp',[[15,1]],'might',[[5,1],[4,2],[20,1],[6,1]],'comprehension',[[5,1]],'serious',[[5,1]],'decimal',[[25,2]],'undone',[[4,1],[2,1],[12,1],[5,1]],'fancy',[[10,1]],'warning',[[24,1],[23,6]],'fading',[[23,1]],'playthrough',[[11,1],[12,1],[10,1],[14,1],[5,2],[2,2],[7,2],[8,2],[9,1],[6,11]],'simply',[[11,1],[20,2],[4,2],[22,1],[25,1],[5,2],[2,2],[7,1],[9,3],[6,4]],'sentences',[[6,1]],'redoing',[[6,1]],'juggle',[[8,1],[7,1]],'manually',[[12,2],[20,3],[4,2],[10,1],[18,1],[22,1],[19,1],[7,1],[2,1],[14,1],[9,2],[11,3]],'finished',[[11,3],[14,1],[4,1],[10,2],[22,1],[5,1],[2,1],[7,1],[8,3],[9,2],[6,3]],'practice',[[3,1],[6,1],[10,2],[1,1],[5,1]],'beyond',[[22,5],[23,1],[9,1],[6,1]],'flower',[[6,2]],'advantage',[[5,1]],'maps',[[23,1]],'architecture',[[22,1],[21,1],[23,1]],'imperfections',[[6,1],[2,1]],'tries',[[24,1],[23,1]],'predefined',[[14,1]],'~17',[[22,1]],'fingers',[[8,3]],'unrestricted',[[21,1],[14,1]],'watching',[[6,4],[20,1],[22,6],[2,1],[8,3],[9,10],[4,1],[10,5],[5,3],[19,1],[14,2],[7,5],[11,2],[12,1]],'videogame',[[6,2]],'possibilities',[[11,1],[12,1],[0,1],[7,1],[1,1],[8,2],[9,1],[6,4]],'quitting',[[23,2]],'category',[[14,1],[17,30],[5,1]],'gradient',[[23,2]],'controlling',[[22,2],[2,1],[16,1],[15,3],[5,2]],'stuff',[[22,2]],'lesser',[[19,1],[22,1]],'offer',[[22,1]],'option',[[22,2],[18,2],[16,2],[5,5],[19,4],[23,1],[7,2],[12,5],[11,33]],'origin',[[16,2]],'incites',[[10,1],[2,1]],'summary',[[13,1],[20,1]],'review',[[1,1],[13,1],[7,1]],'most',[[6,8],[20,3],[22,5],[16,2],[15,1],[2,9],[8,1],[9,2],[3,1],[4,5],[10,1],[5,3],[19,1],[23,1],[14,3],[7,3],[11,5],[12,9]],'forming',[[5,1]],'pastes',[[5,1]],'does',[[6,1],[22,16],[2,2],[25,1],[5,1]],'dividing',[[10,1],[2,1],[9,1],[6,2]],'100001000',[[11,1]],'detects',[[22,2],[25,1],[23,2]],'filled',[[22,1],[24,1],[4,1],[11,1]],'permitted',[[14,1]],'redo',[[22,2],[24,2],[10,1],[15,3],[23,2],[11,1],[6,5]],'reflexes',[[14,1]],'balanced',[[6,1]],'versa',[[22,1],[16,1],[15,1]],'desyncs',[[23,1],[14,1]],'150',[[10,2]],'mechanic',[[14,1],[6,1]],'involuntarily',[[2,1]],'fragment',[[6,1],[5,1]],'points',[[22,3],[24,2],[4,2],[15,1],[23,1],[8,3],[20,1],[9,1]],'influenced',[[6,2]],'fatigability',[[8,1]],'substituted',[[17,4]],'items',[[5,2],[19,1],[22,6],[23,4],[15,2],[11,1]],'radio',[[5,2]],'detaching',[[11,2]],'branch0',[[17,2]],'keys',[[22,8],[24,2],[4,2],[15,7],[5,7],[17,2],[19,1],[25,2],[8,1],[11,20],[9,1]],'sooner',[[5,1]],'exploiting',[[14,1]],'deleted',[[17,1],[19,1]],'historx',[[25,1]],'able',[[3,1],[11,2],[12,5],[18,1],[20,1],[22,4],[5,1],[23,5],[2,3],[7,2],[9,1],[6,1]],'energy',[[14,1],[2,1]],'office',[[22,1]],'converts',[[22,1]],'forth',[[22,1],[4,1],[7,1],[2,1]],'regardless',[[22,1],[5,1]],'imperceptibly',[[11,1]],'relevant',[[20,1],[22,2],[16,1],[11,3],[6,1]],'pass',[[22,1],[8,1],[11,1]],'doubt',[[7,1]],'distant',[[10,2],[7,1],[9,1],[5,1]],'subpixel',[[2,1]],'optimizing',[[23,1],[14,1],[13,1],[6,3]],'creative',[[6,1]],'worse',[[20,1],[9,3],[7,1]],'organization',[[5,1],[4,1],[2,1]],'whatsoever',[[6,1]],'mark',[[22,2],[24,1],[4,1],[15,1],[23,1],[19,1],[14,2],[9,5],[6,5]],'grades',[[22,1]],' movie',[[25,1]],'describing',[[1,1],[12,1],[6,1]],'chapters',[[6,2],[10,1],[2,1]],'appears',[[22,9],[11,2],[15,1],[17,3],[9,1],[3,1],[24,1],[4,1],[10,1],[19,1],[14,1],[12,1],[6,6]],'product',[[14,1]],'once',[[6,2],[22,6],[18,1],[16,1],[2,1],[8,1],[9,2],[4,1],[10,1],[5,3],[14,3],[7,3],[11,2],[12,2]],'solves',[[22,1]],'activation',[[12,1]],'close',[[3,1],[5,1],[10,2],[24,4],[11,3],[6,3]],'pagedown',[[15,3]],'noticeable',[[7,1]],'device',[[25,3],[14,1]],'traverse',[[16,1]],'highlighted',[[22,2],[14,1],[15,2],[5,2]],'follows',[[22,2],[14,1],[7,1],[25,1]],'obstruct',[[19,1]],'greenzoning',[[22,1],[11,1]],'eject',[[24,2],[15,3],[25,2]],'crossed',[[22,1]],'compression',[[11,1],[23,3]],'intentionally',[[14,1]],'clarification',[[11,1]],'operation',[[22,14],[24,1],[4,3],[16,1],[15,1],[23,3],[17,6],[19,1],[2,1],[11,1],[12,1]],'state',[[6,3],[20,7],[18,4],[22,28],[16,3],[15,25],[17,4],[2,1],[8,4],[9,1],[24,12],[4,2],[10,1],[25,5],[5,10],[23,17],[14,6],[7,1],[11,9],[12,3]],'guessed',[[22,1],[5,1]],'labels',[[15,1],[23,1]],'correspond',[[22,3]],'completed',[[7,1]],'universal',[[22,1]],'nearest',[[9,1],[22,4],[16,1],[15,1],[5,3],[2,1],[7,3],[14,1],[11,1],[6,1]],'productive',[[22,1],[11,1]],'shortest',[[20,1]],'speedrunners',[[20,1],[14,1]],'pure',[[7,1]],'equivalent',[[22,1]],'switch',[[20,1],[22,1],[18,2],[15,9],[17,3],[2,1],[8,1],[9,2],[3,1],[24,3],[10,2],[25,2],[5,4],[19,8],[14,1],[7,2],[12,1],[11,1]],'upwards',[[22,1]],'translation',[[0,1]],'seen',[[14,1],[4,1],[5,1]],'store',[[20,1],[22,7],[24,1],[5,1],[23,2],[7,1],[14,3],[8,1],[11,2],[6,1]],'impose',[[2,1]],'birth',[[22,1]],'saying',[[12,1]],'interrupting',[[16,1]],'svn',[[21,3]],'numbers',[[22,12],[4,7],[18,2],[15,1],[5,1],[2,1],[12,1],[20,2]],'helps',[[11,1],[22,1],[4,1],[5,2],[2,1],[12,1],[6,1]],'automates',[[2,1]],'undos',[[22,1],[11,1]],'own',[[6,3],[20,1],[18,1],[15,1],[17,1],[2,3],[8,1],[9,1],[4,2],[10,1],[25,2],[5,2],[23,1],[14,2],[7,1],[11,1],[12,3]],'parabola',[[22,1]],'leaves',[[22,1],[11,1]],'autosave',[[22,2],[24,1],[11,4],[23,2]],'emu',[[12,1],[18,1]],'equal',[[6,1],[22,10],[18,3],[2,1],[5,2]],'abilities',[[2,1]],'location',[[22,2],[2,1]],'instrument',[[8,1]],'ignoring',[[22,1],[23,1]],'horizontally',[[22,2]],'landed',[[6,1]],'transparent',[[23,1]],'worsening',[[9,1]],'straight',[[4,1]],'format',[[22,8],[24,5],[21,1],[25,15],[23,1],[0,1],[2,1],[12,9]],'heartedly',[[6,1]],'recognize',[[11,1]],'definitely',[[14,1],[4,1],[10,1]],'authoring',[[22,1],[10,1],[11,1]],'make',[[6,7],[20,1],[18,1],[22,4],[16,1],[15,2],[17,1],[2,1],[8,3],[3,1],[4,1],[5,12],[19,1],[23,3],[14,2],[7,6],[12,5],[11,6]],'distracting',[[3,1],[7,1]],'equalizing',[[6,1]],'refuses',[[25,2]],'were',[[22,4],[6,3],[18,2],[16,1],[17,4],[2,4],[24,1],[4,5],[25,4],[5,2],[7,1],[14,1],[12,1],[11,4]],'jumps',[[6,1],[22,1],[15,2],[5,3],[7,1],[11,2],[9,1]],'populated',[[3,1]],'written',[[22,1],[23,1],[14,1],[6,1]],'unmarked',[[22,3]],'due',[[22,2],[10,1],[12,1],[5,1]],'lands',[[6,2]],'mini',[[13,1],[12,1]],'spacebar',[[11,2],[23,1],[24,1],[25,1],[15,2],[9,1]],'global',[[12,1]],'sure',[[3,1],[11,2],[10,1],[12,2],[18,1],[20,1],[5,2],[19,1],[7,2],[9,1],[6,1]],'efforts',[[6,2]],'tracking',[[22,2],[16,2]],'assigned',[[22,1],[18,1],[5,2],[17,5],[7,1],[11,5],[9,1]],'exact',[[22,2],[4,1],[16,1],[12,3]],'resync',[[7,1],[6,2]],'watch',[[20,5],[22,2],[16,3],[15,3],[2,1],[8,1],[9,6],[3,1],[4,1],[10,2],[5,1],[14,2],[7,3],[12,5],[6,6]],'can',[[6,32],[20,9],[18,17],[22,88],[16,9],[15,18],[21,1],[17,3],[2,14],[8,7],[9,22],[3,6],[24,16],[4,27],[10,11],[25,5],[5,48],[19,9],[23,6],[14,22],[7,17],[11,33],[12,32]],'keeping',[[10,1],[2,1],[8,2],[9,1]],'turbo',[[10,6],[15,3],[5,2],[23,2],[2,1],[14,3],[9,5]],'intuitive',[[22,3],[8,1]],'cards',[[4,1],[5,1]],'topic',[[19,1]],'desirable',[[22,2]],'attract',[[22,1]],'giving',[[10,1],[2,2]],'essential',[[7,1],[12,2],[2,1]],'too',[[11,7],[22,7],[10,1],[24,1],[15,1],[5,2],[23,2],[2,1],[14,1],[8,2],[9,1],[6,8]],'excessive',[[14,1]],'slot',[[22,8],[6,1],[15,33],[17,6],[8,5],[9,3],[24,8],[10,2],[5,4],[23,1],[7,6],[11,2],[20,6]],'slowest',[[4,1],[15,1]],'newppu',[[25,1]],'bit0',[[25,2]],'keyword',[[25,3]],'compare',[[6,2],[20,5],[10,2],[22,2],[5,2],[19,1],[14,2],[8,3],[11,1],[9,2]],'gets',[[22,1],[4,1],[10,1],[14,1],[8,1],[12,1],[6,1]],'grants',[[6,1]],'orange',[[4,2]],'version',[[22,3],[24,2],[14,1],[2,1],[11,1],[25,9]],'erase',[[17,3],[22,1],[4,1],[10,1],[11,2],[15,1]],'modifier',[[22,4],[24,1]],'discover',[[6,2]],'redefine',[[15,1]],'lets',[[6,1]],'reaching',[[23,1],[8,2],[6,3]],'sound',[[23,1],[14,1],[15,4],[12,1]],'mismatch',[[24,1],[23,1]],'uncontrollable',[[14,1]],'faded',[[6,1]],'facilitate',[[19,2],[4,1],[5,1]],'remap',[[11,1]],'bear',[[6,1]],'fashion',[[22,1]],'reports',[[25,2]],'displayed',[[20,1],[22,27],[4,2],[15,1],[5,4],[25,4],[14,2],[12,1],[11,2]],'indicators',[[6,1]],'smb',[[12,1],[6,1]],'exit',[[22,1],[23,3],[15,3],[6,1]],'branch3',[[17,2]],'guess',[[6,1],[9,2],[2,1]],'0000010',[[4,1]],'shaping',[[12,1],[6,1]],'duties',[[8,1]],'bind',[[22,1],[11,1],[18,2]],'path',[[2,1]],'weeks',[[10,1]],'wide',[[22,1],[4,1]],'either',[[6,4],[20,1],[18,2],[22,6],[15,1],[17,3],[2,2],[9,2],[24,5],[4,2],[25,3],[5,6],[23,2],[7,5],[14,4],[11,3],[12,1]],'mistake',[[21,1],[15,1],[8,5],[9,2],[24,2],[10,2],[5,1],[23,1],[0,1],[7,21],[14,1],[11,1],[6,2]],'noticing',[[12,1],[6,1]],'past',[[10,1],[8,1],[9,1],[5,1]],'post',[[19,1],[7,1],[2,1],[12,1]],'fire',[[22,2],[12,1],[15,3]],'accordance',[[22,1]],'inside',[[9,1],[22,5],[4,1],[21,2],[5,1],[17,1],[0,1],[19,1],[11,1],[12,3]],'library',[[22,1],[18,2],[13,1],[12,1],[23,2]],'interpreted',[[22,1],[18,1],[2,1],[25,1]],'screen',[[20,3],[22,14],[6,3],[2,1],[8,1],[9,3],[4,4],[10,9],[25,2],[5,4],[14,3],[11,1],[12,6]],'busy',[[6,1]],'plays',[[7,2]],'exist',[[18,2],[11,1],[12,1]],'fundamentals',[[1,1]],'code ',[[25,1]],'mouse',[[20,1],[22,34],[16,17],[15,53],[17,3],[2,4],[8,1],[9,14],[3,1],[24,7],[4,11],[10,6],[25,6],[5,18],[19,4],[0,1],[23,5],[14,1],[7,6],[12,3],[11,13]],'longer',[[7,1],[4,1],[2,1]],'super',[[5,1],[4,1],[14,1],[12,1],[6,3]],'assign',[[2,1]],'provide',[[22,3],[18,3],[8,1],[12,2],[23,2]],'accomplished',[[22,2]],'miss',[[3,1],[24,1]],'join',[[6,2]],'exempt',[[7,1]],'retype',[[2,1]],'aimed',[[14,1]],'insert',[[6,1],[22,3],[10,3],[18,2],[24,4],[15,15],[5,12],[17,12],[19,1],[25,2],[11,2],[9,2]],'omit',[[4,1]],'implementing',[[22,1],[6,2]],'quick',[[22,1],[10,2],[7,1],[8,1],[9,1],[11,1]],'subtitle',[[25,4]],'dozen',[[6,2],[22,2],[5,1]],'walks',[[6,1]],'2008',[[22,1]],'reconfiguring',[[11,1]],'detail',[[3,1],[5,1]],'viewers',[[12,2],[6,1]],'fun',[[12,1],[11,1],[6,1]],'replacing',[[24,2],[20,2]],'discard',[[8,2],[10,2],[18,1]],'ride',[[5,1]],'why',[[11,1],[4,2],[10,1],[19,4],[2,1],[7,1],[8,1],[9,1],[6,1]],'then',[[6,13],[20,6],[18,1],[22,25],[16,1],[15,2],[17,25],[2,4],[8,2],[9,2],[24,1],[4,7],[10,2],[25,7],[5,10],[19,2],[23,3],[14,3],[7,6],[11,14],[12,13]],'subtask',[[14,1],[6,2]],'discretion',[[6,1]],'todo',[[12,2]],'0x3ad',[[12,2]],'wouldn',[[14,1]],'branching',[[19,1],[22,1],[11,1]],'superimposed',[[22,1]],'mind',[[12,4],[20,4],[4,4],[10,1],[22,1],[5,1],[2,2],[7,1],[8,1],[9,1],[6,8]],'misconception',[[24,1]],'orientation',[[12,1]],'bottom',[[22,3],[16,1],[12,1],[5,1]],'concept',[[22,1],[14,1],[12,1],[23,1]],'moved',[[22,3],[23,2],[5,1]],'limit',[[9,1],[6,2]],'delivered',[[7,1]],'outrun',[[8,1]],'choose',[[6,7],[20,3],[4,2],[15,1],[5,3],[17,18],[19,3],[7,2],[12,7],[11,4]],'analyzing',[[22,1],[6,2]],'tools',[[3,1],[18,2],[5,1],[23,1],[2,7],[14,3],[8,2],[12,2],[6,1]],'means',[[6,5],[20,3],[18,1],[22,3],[16,1],[2,2],[8,2],[9,1],[4,1],[25,2],[23,2],[19,2],[14,1],[7,3],[11,2],[12,1]],'walkthrough',[[14,6],[6,3]],'dispatch',[[23,1]],'minimized',[[12,1]],'fm3',[[22,5],[24,9],[21,1],[25,10],[23,1],[17,1],[0,1],[19,2],[2,2],[11,6],[12,17]],'drawbox',[[12,2]],'emerging',[[20,1]],'transposed',[[19,1]],'closest',[[16,2],[6,1]],'buttonpress',[[11,3],[9,6],[10,6],[22,1],[16,1],[12,1],[20,1]],'recorded',[[22,7],[25,1],[5,4],[7,1],[8,2],[12,1],[11,1]],'immensely',[[5,1]],'reality',[[10,1]],'programmers',[[2,1]],'serving',[[12,1]],'middleclick',[[24,3]],'author',[[22,1],[25,3],[23,1],[19,2],[0,2],[1,1],[12,1],[6,4]],'denying',[[14,2]],'encourages',[[2,1]],'branch2',[[17,2]],'erasing',[[11,1],[15,2],[4,1],[9,1],[5,2]],'images',[[23,1],[14,1],[12,1],[5,1]],'calculations',[[23,1],[7,1]],'playarounds',[[14,1]],'ensures',[[22,1],[23,2],[15,1],[6,1]],'accepted',[[22,2],[12,1]],'versatile',[[22,1]],'popup',[[23,6]],'simplistic',[[14,1]],'docopy',[[12,3]],'may',[[6,19],[20,3],[18,5],[22,11],[2,3],[8,5],[9,8],[24,1],[4,9],[10,4],[25,2],[5,9],[23,4],[14,2],[7,4],[11,16],[12,12]],'detect',[[22,1],[10,1],[7,1],[14,1],[9,1]],'imported',[[17,2],[19,1]],'stands',[[5,1]],'client',[[21,1]],'descriptions',[[6,1],[22,1],[15,1],[11,4]],'spent',[[4,1],[2,1],[14,1],[9,1],[6,1]],'burst',[[12,1]],'labor',[[22,1]],'violet',[[4,1]],'jumpprevmarker',[[24,1]],'export',[[19,1],[2,1],[12,3],[23,1]],'offers',[[2,1]],'anything',[[7,1],[15,1],[6,1]],'srt',[[12,2]],'network',[[12,1]],'animations',[[23,2]],'seekng',[[23,1]],'sifc_none',[[25,1]],'follow',[[22,1],[10,2],[16,3],[15,5],[5,2],[23,1],[2,1],[8,1],[11,2],[9,4]],'course',[[22,2],[10,1],[5,1],[0,1],[2,1],[1,1],[7,3],[11,1],[6,3]],'small',[[6,12],[22,3],[24,2],[5,3],[7,2],[14,1],[20,1],[11,2]],'divide',[[4,1],[6,3]],'access',[[22,1],[23,3],[14,1],[11,2],[12,1]],'deserialize',[[25,1]],'however',[[6,1],[12,1],[10,1],[22,4],[5,1],[14,1],[8,2],[11,2],[9,3]],'black',[[19,1],[22,1],[4,1],[11,3]],'approaches',[[11,3],[20,16],[10,7],[5,3],[7,2],[14,2],[8,7],[9,5],[6,4]],'representing',[[24,1],[18,6],[14,1],[23,1]],'finishing',[[8,1],[14,1]],'committed',[[7,1]],'skipped',[[24,1]],'reaches',[[22,1],[6,1]],'developers',[[14,1],[6,1]],'moves',[[5,8],[22,6],[10,2],[25,1],[6,2]],'movie',[[6,23],[20,3],[18,12],[22,85],[16,26],[15,19],[17,23],[2,4],[8,14],[9,8],[3,1],[24,23],[4,24],[10,4],[25,14],[5,53],[19,9],[23,30],[7,12],[13,2],[14,27],[11,33],[12,22]],'held',[[22,2],[24,2],[4,2],[16,1],[15,2],[5,1],[23,1],[2,1],[6,1]],'popup_display',[[23,1]],'about',[[6,7],[20,2],[18,1],[22,16],[16,2],[15,1],[2,2],[8,1],[9,3],[3,1],[24,5],[4,5],[5,5],[23,10],[0,1],[14,5],[7,2],[11,9],[12,1]],'vertical',[[22,2],[4,2],[16,2],[12,1],[23,1]],'fixed',[[19,1],[22,3],[7,5],[14,3],[25,1],[6,1]],'bit6',[[25,2]],'informative',[[22,1]],'users',[[19,1],[22,1],[4,1],[5,1]],'sorts',[[7,1]],'being',[[15,1],[20,1],[7,3],[2,2],[12,2],[5,1]],'transition',[[22,1],[12,1]],'relative',[[22,3]],'pdf',[[19,1],[0,1],[25,1],[16,1],[9,1],[21,1]],'extraordinary',[[14,1],[2,2]],'specifically',[[22,2],[4,1]],'suppose',[[12,1],[10,1],[8,1],[9,1],[6,1]],'mute',[[15,1],[23,1]],'callbacks',[[18,8]],'pays',[[10,1]],'processes',[[23,1]],'concentrates',[[14,1]],'division',[[6,1]],'naked',[[14,1]],'combination',[[12,2],[4,1],[10,3],[15,1],[2,1],[7,1],[11,1],[6,1]],'few',[[5,2],[22,3],[4,2],[7,1],[9,1],[6,1]],'comfort',[[11,2],[10,1],[2,1]],'contains',[[3,2],[22,4],[4,3],[24,1],[16,2],[5,4],[17,1],[19,2],[23,1],[14,3],[12,3],[11,1]],'lot',[[12,1],[22,3],[10,1],[11,3],[6,2]],'array',[[22,9],[18,1],[23,13]],'advantageous',[[10,1],[7,2],[8,1],[20,1]],'repetitive',[[6,1]],'unintended',[[24,1],[14,1]],'multitude',[[5,1],[22,1],[20,1],[6,2]],'xxx',[[25,2]],'reproduce',[[19,1],[8,1],[7,2]],'scale',[[3,1],[5,1],[22,1],[14,1],[23,2],[6,3]],'deliberately',[[14,1]],'silently',[[11,2]],'memorize',[[20,1],[7,1]],'hardcore',[[6,1]],'editors',[[3,1],[2,1]],'tag',[[12,1],[6,1]],'snowslide',[[6,1]],'ended',[[11,1]],'supported',[[19,1],[24,2],[25,3]],'prompts',[[19,1],[23,1],[5,1]],'near',[[17,3],[22,2],[4,1],[9,1],[6,1]],'applies',[[23,1],[18,1],[14,1],[15,1],[5,1]],'deterministic',[[23,1],[14,2]],'partial',[[23,3],[12,1],[20,1]],'understand',[[10,1],[7,1],[21,1],[12,2]],'improvable',[[7,1]],'optimality',[[12,1],[20,2],[10,6],[22,2],[5,1],[7,4],[14,1],[8,3],[9,5],[6,18]],'moreover',[[22,1],[4,1],[15,1],[6,1]],'draw',[[9,2],[22,2],[4,2],[10,4],[15,1],[5,2],[17,1],[14,1],[11,6],[12,1]],'registering',[[18,4]],'touch',[[22,1],[6,1]],'mode',[[22,7],[18,2],[15,9],[17,2],[8,2],[9,1],[3,1],[24,5],[10,1],[5,3],[23,2],[7,9],[14,2],[11,2]],'pointers',[[25,1],[14,1]],'timesavers',[[14,2]],'conversion',[[23,1]],'toggle',[[5,1],[22,1],[23,3],[24,3],[15,15],[11,2]],'statistics',[[22,1]],'killed',[[8,1]],'hampered',[[6,1]],'chm',[[21,1],[9,1],[12,1]],'them',[[6,9],[20,1],[18,2],[22,9],[16,1],[15,1],[17,1],[2,1],[8,3],[9,4],[24,1],[4,9],[10,1],[25,1],[5,4],[19,2],[23,3],[14,3],[11,10],[12,5]],'farther',[[15,1]],'cpp',[[23,22]],'numbering',[[22,1]],'thin',[[22,1]],'2gb',[[22,1]],'occupied',[[15,2],[17,3],[4,2],[11,2],[6,1]],'getmarker',[[18,2]],' two',[[20,2]],'icons',[[20,1],[22,11],[4,1],[24,1],[16,3],[15,2],[5,1],[12,1],[11,1]],'motivate',[[12,1]],'rather',[[11,1],[12,3],[4,1],[10,1],[24,1],[5,2],[2,2],[7,2],[9,1],[6,2]],'improved',[[22,1],[6,1]],'evaluated',[[14,1],[6,1]],'limited',[[22,2],[14,2],[8,1],[6,2]],'extensions',[[12,1]],'2012',[[22,1]],'psx',[[22,1]],'respectively',[[15,2],[20,1]],'keypresses',[[7,1],[11,2],[5,1]],'actual',[[22,2],[4,2],[18,5],[21,1],[5,3],[2,1],[14,1],[12,2],[6,2]],'searching',[[6,1],[20,1],[10,2],[22,3],[16,4],[5,1],[23,4],[14,1],[12,2],[11,2]],'backups',[[8,2]],'suddenly',[[6,1]],'white',[[15,2],[22,1],[4,1],[11,1],[5,1]],'voltage',[[22,1]],'know',[[3,1],[12,5],[10,3],[18,1],[22,1],[0,1],[2,1],[7,2],[9,1],[6,2]],'entire',[[9,1],[22,3],[4,1],[25,1],[5,1],[19,1],[2,1],[11,2],[12,1]],'player',[[11,3],[12,4],[4,1],[15,1],[5,6],[23,2],[25,4],[2,2],[7,4],[14,14],[9,1],[6,7]],'useless',[[24,1],[10,1],[14,1],[9,2]],'volume',[[9,1],[15,3]],'strokes',[[2,1]],'evil',[[19,1]],'whitish',[[4,1]],'their',[[6,2],[20,1],[22,2],[15,1],[2,1],[8,2],[9,1],[24,2],[4,1],[25,2],[5,3],[23,1],[14,2],[1,1],[7,1],[11,2],[12,6]],'cut',[[17,5],[15,2],[5,1]],'column',[[20,1],[22,30],[4,8],[24,3],[16,5],[15,8],[5,2],[19,1],[25,2],[12,4],[11,5]],'acceleration',[[7,1],[8,2],[12,6],[6,5]],'somebody',[[14,1]],'bookmarks',[[6,2],[20,10],[22,52],[16,3],[15,8],[17,3],[8,11],[9,3],[24,3],[4,1],[25,5],[5,27],[19,3],[23,15],[7,3],[14,4],[11,8],[12,3]],' submitinsertframes',[[22,1]],'way',[[6,9],[20,1],[22,9],[16,2],[15,7],[2,7],[8,3],[9,5],[24,1],[4,9],[10,5],[5,6],[19,4],[23,1],[14,6],[7,4],[11,17],[12,7]],'nil',[[22,1],[12,1],[18,7]],'copies',[[17,1],[7,1],[12,1],[5,3]],'specified',[[22,1],[25,2]],'existing',[[3,1],[22,2],[18,1],[15,2],[5,4],[19,1],[7,1],[14,2],[8,3],[12,1],[9,1]],'locked',[[24,1]],'grasp',[[6,1]],'aloof',[[6,1]],'playback',[[20,2],[22,61],[18,8],[16,25],[15,30],[17,4],[2,1],[8,3],[9,16],[24,8],[4,17],[10,12],[5,33],[19,3],[23,12],[14,6],[7,5],[12,6],[11,16]],'variations',[[10,1]],'expands',[[8,1],[5,1]],'reverts',[[5,1]],'creates',[[22,2],[24,1],[10,1],[25,2],[23,2],[7,2],[12,3]],'vibrating',[[14,1]],'improvements',[[22,2],[7,1],[14,1],[6,2]],'accomplishment',[[8,1]],'somewhere',[[17,1],[8,1],[15,1],[16,1]],'accordingly',[[22,2],[4,1]],'bros',[[5,1],[4,1],[14,1],[12,1],[6,3]],'fit',[[22,3],[16,1],[18,3]],'rows',[[22,8],[23,4],[14,1],[15,4],[5,2]],'unobvious',[[21,1],[7,1]],'string',[[25,4],[18,13],[20,1]],'term',[[22,1],[2,1],[14,2],[12,1],[6,2]],'suggests',[[24,2]],'bytes',[[25,13]],'comments',[[22,1],[4,1],[2,3]],'avoids',[[6,1]],'abstracting',[[2,1]],'thrill',[[6,1]],'enemies',[[20,2],[6,3]],'wasn',[[22,2],[18,2],[23,1]],'authors',[[14,1],[6,1]],'reconfigure',[[11,1]],'twice',[[22,3],[4,2],[16,2],[15,2],[12,3]],'decomposed',[[2,1]],'responses',[[10,1]],'happens',[[20,1],[4,2],[7,1]],'resized',[[22,2]],'couple',[[4,1],[7,1],[8,1],[12,1],[5,1]],'peculiarities',[[14,1]],'illuminate',[[15,1]],'segmentation',[[6,1],[2,1]],'nice',[[12,1],[2,1]],'need',[[6,5],[20,2],[22,14],[16,21],[15,5],[21,2],[2,4],[8,5],[9,5],[24,1],[4,3],[10,8],[25,1],[5,8],[23,1],[0,1],[7,9],[11,15],[12,18]],'conduct',[[10,1]],'dissect',[[14,1]],'accompany',[[6,1]],'accustomed',[[22,1],[6,1]],'platformer',[[6,1]],'total',[[22,1],[25,1],[11,2],[5,1]],'require',[[22,2],[24,1],[14,2],[12,1],[6,4]],'writing',[[6,1],[25,2],[12,3],[23,2]],'entertainment',[[20,2],[14,2]],'efficiently',[[2,1]],'edit',[[6,1],[20,1],[22,11],[16,2],[15,4],[17,13],[2,1],[9,3],[3,2],[4,8],[10,1],[5,4],[7,1],[14,3],[11,5],[12,2]],'trajectory',[[10,1],[7,1]],'dashes',[[11,1]],'automated',[[22,1]],'useful',[[12,5],[20,1],[10,2],[22,5],[15,4],[5,1],[2,1],[1,1],[14,2],[11,5],[6,5]],'finger',[[8,1],[4,2],[6,1]],'card',[[5,4]],'spends',[[2,1]],'consecutive',[[19,1],[18,2],[11,2],[6,1]],'act',[[12,1],[2,1]],'generated',[[25,1]],'execution',[[12,2],[2,1]],'understood',[[11,1]],'trembling',[[11,1]],'compatible',[[5,1]],'basis',[[22,1]],'emuversion',[[25,1]],'operational',[[22,1]],'replaying',[[11,1],[6,1],[25,1],[5,2],[8,1],[12,2],[20,2]],' in',[[7,1]],'compared',[[14,1],[6,1]],'typing',[[15,1],[4,1],[7,1],[8,1],[11,1],[12,2]],'serve',[[8,1]],'looking',[[22,1],[8,1],[4,1]],'has',[[20,1],[11,5],[18,2],[22,23],[16,1],[17,1],[9,1],[24,1],[4,2],[10,1],[25,1],[5,10],[14,2],[12,1],[6,5]],'software',[[5,1]],'incorrect',[[8,1],[10,1]],'motion',[[10,1],[14,1]],'optimum',[[14,1]],'ebooks',[[13,1],[4,1]],'inserting',[[19,1],[22,2],[23,1],[9,1],[11,1]],'streamlines',[[23,2]],'download',[[21,1]],'irrelevant',[[22,2],[4,1],[25,2],[5,1],[23,1],[2,1],[9,1],[6,1]],'spectrum',[[10,1]],'decreases',[[11,1],[6,1]],'otherwise',[[22,2],[4,1],[18,1],[15,1],[5,1],[17,1],[11,2]],'highlighting',[[22,3]],'regularities',[[9,1],[6,1]],'value',[[11,3],[20,5],[18,1],[22,20],[25,14],[5,1],[23,2],[2,1],[14,1],[12,1],[6,8]],'700',[[8,1]],'behave',[[9,1]],'additionally',[[24,1],[10,1],[7,1]],'visualizes',[[22,1]],'foresee',[[9,1]],'strings',[[20,1]],'here',[[6,3],[20,3],[22,2],[17,1],[2,2],[8,1],[9,3],[3,2],[10,3],[5,3],[19,1],[0,1],[23,5],[14,1],[7,2],[11,3],[12,4]],'fledged',[[10,1],[6,1]],'operate',[[14,2]],'signals',[[23,1]],'length',[[23,2],[25,5],[5,1]],'recurring',[[2,1]],'land',[[10,1],[6,1]],'sprite',[[10,1],[14,2]],'step',[[20,2],[10,4],[15,2],[5,4],[7,1],[2,2],[8,10],[9,3],[14,2]],'advanced',[[22,4],[18,1],[16,1],[5,1],[19,1],[0,1],[14,4],[1,1],[12,2]],'subject',[[25,1],[14,1]],'rarefied',[[22,1]],'setnote',[[17,2],[18,2]],'scripts',[[22,2],[18,4],[2,1],[12,8]],'changes',[[6,1],[22,32],[18,14],[16,2],[15,6],[17,1],[2,1],[9,1],[3,1],[24,1],[4,6],[10,3],[5,6],[19,1],[23,20],[7,2],[14,1],[11,14],[12,3]],'trial',[[14,1],[9,1],[10,2]],'consequence',[[6,1]],'default',[[22,3],[18,1],[16,1],[15,3],[8,1],[3,1],[24,3],[4,2],[25,2],[5,7],[23,5],[11,30],[6,1]],'consequences',[[10,1],[2,1]],'looped',[[12,1]],'convention',[[25,2]],'indicates',[[25,1]],'words',[[12,6],[25,1]],'modified',[[15,1],[10,1],[18,1],[12,1],[11,2]],'habits',[[19,1],[22,1],[2,1],[8,1]],'examples',[[17,29],[18,1],[14,8]],'integer',[[20,2],[25,6]],'process',[[6,12],[20,4],[22,5],[17,2],[2,6],[8,2],[9,2],[4,1],[10,4],[5,7],[19,1],[0,1],[23,3],[7,5],[1,2],[14,6],[11,4],[12,5]],'page',[[22,2],[24,3],[16,6],[15,2],[5,9]],'unequal',[[22,1]],'afraid',[[4,1],[9,1]],'newly',[[22,6],[8,2],[11,1],[5,1]],'dialog ',[[23,1]],'speak',[[5,1]],'mentioned',[[23,1]],'tool',[[22,3],[5,1],[23,6],[14,3],[1,1],[20,1],[12,3]],'shooting',[[5,1],[12,2],[9,4],[6,1]],'ready',[[10,2],[2,1],[11,1],[5,1]],'executed',[[22,2],[23,1],[9,1],[12,5]],'selectively',[[22,2]],'painting',[[22,1]],'overtakes',[[6,1]],'polish',[[10,2],[9,1],[7,3]],'obtained',[[22,1]],'soft',[[25,2]],'walkthroughs',[[14,1]],'wants',[[22,2]],'tell',[[10,1],[4,1],[5,1]],'engine',[[23,2],[14,1],[11,1],[6,2]],'branch9',[[17,2]],'eof',[[25,1]],'optimally',[[8,1],[12,1],[6,1]],'compensating',[[2,1]],'physical',[[5,1]],'perfectness',[[7,1],[6,3]],'used',[[6,1],[22,12],[15,5],[17,30],[2,2],[8,9],[9,2],[3,3],[24,8],[4,2],[10,1],[25,16],[5,9],[23,4],[7,8],[13,1],[14,12],[11,9],[12,5]],'submenu',[[11,3]],'trick',[[6,9],[14,1],[2,3]],'menus',[[19,1],[15,1]],'missing',[[22,1],[5,1]],'calls',[[22,3],[25,2]],'master',[[8,2],[12,3]],'aware',[[11,1],[7,1],[9,1],[6,1]],'expected',[[20,1],[2,1],[13,1],[14,1],[12,2],[6,2]],'functionality',[[22,2],[2,2],[21,1],[5,1]],'label',[[15,1],[4,6],[16,2],[12,2],[5,2]],'numeric',[[5,1],[22,2],[12,1],[11,2]],'general',[[9,1],[14,1],[4,1],[10,2],[20,2],[22,1],[2,1],[1,1],[7,1],[8,1],[6,1]],'bit7',[[25,2]],'convenience',[[19,1],[4,1],[2,1],[5,1]],'exhausted',[[20,2]],'careful',[[14,1]],'this',[[22,74],[11,57],[18,11],[6,20],[15,20],[2,9],[8,15],[9,17],[3,3],[25,6],[7,18],[1,1],[13,1],[16,7],[21,1],[17,3],[24,10],[4,24],[10,14],[5,36],[19,4],[0,2],[23,2],[14,11],[12,29],[20,9]],'excel',[[6,1]],'says',[[22,2]],'emulated',[[6,1],[22,6],[4,1],[16,1],[15,1],[5,2],[23,2],[14,4],[12,1],[11,2]],'temporarily',[[8,1],[4,1],[11,1]],'primarily',[[22,1]],'straightforwardly',[[5,1]],'three',[[22,2],[7,2],[20,1],[5,2]],'branches',[[11,1],[22,17],[18,1],[16,2],[15,4],[17,3],[2,4],[24,4],[5,12],[19,2],[23,11],[7,2],[14,3],[20,1],[12,1]],'causing',[[12,1]],'shrink',[[22,1],[23,1],[6,1]],'byte',[[22,1],[18,1],[25,9]],'algorithm',[[22,2],[12,2],[14,1]],'bits',[[18,1],[25,3]],'light',[[22,6],[24,1],[4,5],[10,1],[16,1],[15,1],[5,15],[14,2],[8,1],[11,3],[6,2]],'distributing',[[23,1]],'leave',[[6,1],[12,5],[4,1],[10,3],[20,1],[16,1],[15,1],[22,3],[8,1],[11,5],[9,1]],'pasteinsert',[[17,5],[15,1]],'inspects',[[23,1]],'whose',[[17,1],[22,8]],'fresh',[[6,1]],'reasonable',[[8,1],[11,1],[6,2]],'screenshot',[[22,6],[15,4],[5,1],[19,1],[23,5],[14,3],[11,3]],'configure',[[11,5]],'caring',[[24,1],[2,1],[11,1],[5,1]],'performing',[[5,1]],'bird',[[2,1]],'graph',[[5,3]],'absolute',[[6,1]],'sequencers',[[14,1]],'believe',[[6,1]],'based',[[22,5],[23,1],[4,1],[6,2]],'skips',[[11,1]],'condition',[[24,1]],'сохраняются',[[22,1]],'let',[[3,1],[12,2],[4,2],[22,2],[5,1],[7,1],[9,2],[6,2]],'provides',[[22,5],[23,3],[5,1]],'semi',[[12,1]],'responsible',[[3,1],[22,2],[4,1],[8,2],[15,3]],'criteria',[[20,2],[7,1]],'subfolder',[[12,2],[18,1]],'representation',[[22,1],[25,1],[14,1]],'inaccuracy',[[14,1]],'maximizing',[[6,2]],'accompanying',[[14,1]],'overwritten',[[17,1],[7,1],[11,1],[5,1]],'beautiful',[[22,1],[7,1]],'integrated',[[0,1],[12,1]],'head',[[22,6],[11,2],[12,1]],'coincide',[[14,1]],'reverting',[[11,1]],'premise',[[23,2],[6,1]],'apply',[[6,1],[22,2],[10,1],[18,1],[15,2],[23,2],[7,2],[8,1],[12,4],[11,1]],'hedgehog',[[14,1]],'immediate',[[22,1],[5,2]],'rewrite',[[8,2],[7,1]],'difficulties',[[6,1]],'claim',[[12,1]],'requirement',[[20,1]],'another',[[20,1],[6,7],[22,3],[21,1],[15,2],[17,4],[9,2],[24,1],[4,1],[10,1],[5,5],[23,2],[7,4],[14,5],[11,5],[12,6]],'reflects',[[19,1],[22,1],[12,1],[23,1]],'#selection_table',[[12,1]],'emphasizes',[[14,1]],'efficient',[[10,1]],'letter',[[4,2]],'applychanges',[[23,1]],'observing',[[19,1],[16,1]],'trends',[[1,1]],'runs',[[6,2],[22,1],[4,1],[10,1],[18,2],[5,1],[23,1],[12,3],[11,5]],'usage',[[2,1],[1,1],[8,1],[12,6],[5,1]],'dragged',[[17,1]],'named',[[17,1],[22,1],[2,1],[23,1]],'backslash',[[15,1]],'registers',[[22,1],[12,2],[18,2]],'behavior',[[6,3],[24,3],[16,1],[2,1],[14,1],[12,1],[11,4]],'depicted',[[14,1]],'dummy',[[25,2]],'projected',[[22,1]],'caused',[[17,1],[14,1]],'piano_roll',[[25,1],[23,1]],'resend',[[23,1]],'adapt',[[8,1],[10,1],[11,1]],'relaxation',[[6,1]],'attempting',[[9,1]],'unfinished',[[6,1]],'backspace',[[15,2],[11,1],[5,1]],'releasing',[[24,1],[12,1]],'script',[[17,5],[22,2],[18,7],[12,16],[15,2]],'mood',[[12,1]],'recreate',[[19,1],[12,1]],'reacts',[[23,3]],'simultaneous',[[10,1]],'ensure',[[5,1],[24,1],[7,1],[6,1]],'forums',[[12,1],[2,2]],'repetition',[[12,1]],'window',[[6,2],[20,1],[18,1],[22,25],[16,3],[15,7],[2,1],[3,12],[24,9],[4,6],[10,6],[5,8],[19,3],[23,11],[14,1],[12,11],[11,11]],'line',[[22,20],[24,1],[4,11],[25,3],[5,7],[17,3],[14,1],[12,4],[11,3]],'averts',[[6,1]],'justify',[[2,1]],'reveals',[[21,1],[6,1]],'modification',[[22,1],[10,6],[21,1],[5,1],[17,3],[23,4],[7,4],[14,2],[9,3]],'cursors',[[22,2],[4,1]],'porting',[[22,1],[21,1],[24,1]],'you',[[6,120],[20,33],[18,23],[22,101],[16,42],[15,46],[21,3],[17,2],[2,43],[8,49],[9,65],[3,13],[24,3],[4,71],[10,45],[25,1],[5,99],[19,14],[0,3],[7,55],[14,8],[11,141],[12,102]],'above',[[9,2],[20,3],[4,9],[22,9],[16,6],[15,2],[5,6],[19,1],[11,7],[12,2]],'taseditor_window',[[23,1]],'thorough',[[14,1]],'parameter',[[17,1],[11,1]],'striving',[[16,1],[6,1]],'achieved',[[20,1],[2,2]],'patience',[[2,1]],'must',[[22,4],[6,2],[18,1],[16,1],[2,1],[8,1],[24,1],[25,6],[5,2],[19,1],[23,3],[7,1],[12,1],[11,3]],'response',[[23,1]],'removed',[[19,1],[22,3],[4,2],[24,1],[11,2]],'contradict',[[24,1],[6,3]],'piano',[[20,2],[22,68],[16,23],[15,33],[17,17],[2,1],[8,1],[9,3],[3,3],[24,3],[4,20],[10,2],[25,4],[5,13],[19,5],[23,12],[14,17],[7,1],[12,8],[11,20]],'invalidation',[[18,1]],'arising',[[13,1]],'examined',[[20,1]],'unnatural',[[4,1]],'span',[[11,1]],'look',[[12,1],[22,1],[4,1],[10,3],[5,2],[0,1],[2,1],[7,1],[8,1],[11,2],[6,1]],'express',[[6,1]],'neighbor',[[11,1],[5,1]],'strategies',[[22,1],[24,1],[7,1],[14,1],[8,1],[11,3]],'rely',[[20,2],[9,1],[6,1]],'redrawn',[[22,1],[12,1]],'ascii',[[25,1]],'wasted',[[6,1]],'stays',[[4,1],[9,1]],'recovered',[[22,2]],'scenes',[[9,1],[10,1]],'nameless',[[24,3]],'sensibly',[[12,1],[6,1]],'ago',[[22,1],[4,1],[2,1],[11,4]],'eventually',[[4,1],[6,1]],'confine',[[12,1],[2,1]],'notice',[[6,4],[24,1],[4,1],[2,3],[11,1],[5,2]],'ctrl',[[22,19],[16,11],[15,43],[17,6],[9,3],[3,2],[24,11],[4,5],[10,3],[5,18],[14,1],[12,5],[11,5]],'first',[[6,8],[20,2],[18,3],[22,20],[16,1],[17,14],[2,4],[8,5],[9,6],[24,2],[4,9],[10,7],[25,5],[5,6],[19,2],[0,1],[23,4],[7,5],[11,10],[12,14]],'shoot',[[5,2],[20,1],[9,1],[6,2]],'resyincing',[[6,1]],'etc',[[3,1],[6,1],[22,6],[5,1],[23,2],[14,5],[8,2],[12,1],[9,1]],'regard',[[6,2]],'prohibit',[[23,1]],'fixing',[[7,8],[8,1],[6,2]],'instant',[[11,4],[12,1],[10,2],[22,3],[9,2],[5,1]],'deleting',[[17,2],[19,1],[14,1],[23,3]],'dramatically',[[22,1],[12,2],[6,1]],'rendering',[[8,1]],'rerecords',[[22,4],[7,1],[2,1],[14,1],[6,1]],'100',[[22,1],[25,2],[10,2],[11,5],[6,2]],'except',[[17,1],[25,1],[4,1],[16,2],[15,1],[12,2]],'triggers',[[5,1]],'stopseeking',[[18,2]],'unset',[[17,3],[22,1],[11,2],[15,1]],'simple',[[20,2],[6,5],[22,3],[2,2],[8,2],[9,1],[3,1],[10,2],[25,1],[5,2],[14,1],[7,1],[11,2],[12,4]],'hello',[[17,1]],'tired',[[8,1],[20,3],[2,1]],'zone',[[14,1],[23,1],[2,1]],'despite',[[5,1],[22,1],[12,1],[6,1]],'1200',[[22,4]],'modules',[[25,7],[23,4]],'sequencing',[[4,1]],'alone',[[6,1]],'joyful',[[6,1]],'insignificant',[[4,1]],'slots',[[22,2],[24,2],[5,2],[7,6],[14,1],[8,6],[20,1],[11,1]],'interact',[[22,1]],'priority',[[22,1]],'recalling',[[12,1]],'revise',[[6,1]],'manner',[[19,1],[12,1],[15,1]],'builds',[[2,1]],'questions',[[13,1],[19,1]],'storing',[[22,2],[6,1],[23,1],[14,3],[8,4],[11,1],[9,1]],'showing',[[4,1]],'tweaking',[[22,2],[10,1]],'specifics',[[22,1],[11,1]],'relations',[[23,2]],'canceled',[[22,1]],'calculates',[[23,1]],'symbolizes',[[22,1],[5,1]],'loops',[[12,1]],'clearly',[[22,1],[7,1],[12,1],[6,1]],'least',[[22,5],[4,1],[15,1],[5,1],[17,3],[23,1],[14,1],[12,3],[6,1]],'spontaneous',[[6,1]],'file',[[22,18],[21,1],[17,3],[8,1],[3,6],[24,26],[25,15],[5,1],[19,4],[23,24],[14,1],[12,42],[11,4]],'prepare',[[4,1],[7,1],[8,1],[12,1]],'infinite',[[12,1]],'resist',[[2,1]],'additional',[[22,5],[10,1],[5,1],[19,1],[23,1],[1,1],[8,1],[11,3],[6,1]],'whereas',[[22,1]],'man',[[6,1],[2,1]],'emotional',[[6,1],[7,1],[2,1]],'armed',[[12,1]],'compound',[[20,1]],'formula',[[20,2]],'stereotypes',[[2,2]],'consuming',[[2,1]],'disabling',[[24,1],[11,1]],'matter',[[6,1],[15,1],[2,1],[11,1],[5,1]],'routine',[[12,1],[5,1]],'dumped',[[15,1]],'neighboring',[[22,1]],'featured',[[24,1],[18,1]],'agreement',[[24,1]],'3rd',[[22,4],[25,1],[10,2],[20,1],[5,1]],'putting',[[9,1]],'brainer',[[12,1]],'modifications',[[6,1],[10,1],[23,3],[17,1],[7,2],[11,1],[9,1]],'accounting',[[5,1]],'dictate',[[2,1]],'pixels',[[22,7],[6,1]],'encourage',[[21,1]],'property',[[20,3]],'emulates',[[5,1]],'chain',[[9,1]],'got',[[8,1],[12,1]],'sets',[[22,1],[18,2],[23,1]],'quarter',[[17,1]],'ignore',[[6,1],[18,6],[2,1]],'appearance',[[3,1],[22,1],[12,2],[23,2]],'become',[[14,1],[22,3],[4,5],[10,2],[18,1],[15,3],[5,1],[2,2],[7,1],[8,2],[11,3],[6,2]],'nearby',[[16,2],[11,1],[23,1]],'area',[[22,6],[24,1],[16,2],[15,4],[5,1],[23,1],[12,1],[11,3]],'meaning',[[5,1],[23,1],[12,1],[6,1]],'direction',[[5,1],[22,1],[10,1],[7,1],[24,1],[6,1]],'attribute',[[22,1]],'very',[[6,6],[20,1],[22,3],[16,1],[17,8],[2,3],[8,2],[9,2],[3,1],[4,4],[10,3],[5,3],[23,2],[14,1],[7,4],[11,2],[12,4]],'windows',[[3,1],[22,6],[4,1],[23,5],[11,1],[15,3]],'cheats',[[15,1]],'convenient',[[5,1],[22,1],[12,1],[6,1]],'provided',[[17,1],[22,1],[18,2],[16,2],[9,1]],'logic',[[23,1],[10,1],[2,1],[14,1],[8,1],[6,2]],'literally',[[11,1]],'root',[[22,1],[5,1]],'info',[[23,9],[11,1],[5,4]],'constructed',[[14,1]],'9px',[[22,2]],'tapping',[[4,2],[12,1]],'criticize',[[6,1]],'increments',[[22,3]],'opens',[[24,1],[11,1]],'applied',[[5,1],[17,1],[23,1],[14,1],[12,2],[6,2]],'searches',[[22,2],[23,1]],'getsuperimpose',[[18,2]],'sense',[[22,2],[7,1],[12,1],[11,1]],'think',[[6,4],[22,3],[10,2],[19,2],[7,1],[8,2],[12,2],[9,3]],'shouldn',[[23,2],[10,1],[8,1],[6,1]],'satisfying',[[9,1]],'guid',[[25,1]],'fields',[[22,2],[25,1],[10,1],[15,1],[11,1]],'laziness',[[6,1]],'occurred',[[24,1],[4,1],[18,1]],'font',[[22,1],[4,1]],'identify',[[22,1]],'cleans',[[11,1]],'odd',[[11,1]],'proper',[[12,1]],'kindle',[[13,1],[4,1],[15,1]],'detached',[[22,3],[11,1]],'exactly',[[9,1],[6,3],[22,1],[16,1],[7,2],[2,1],[11,2],[12,2]],'orderly',[[8,1]],'highest',[[22,1],[5,1]],'interpret',[[25,1],[4,1],[18,1]],'pits',[[6,1]],'september',[[22,1]],'depend',[[22,2],[18,1],[25,1]],'switched',[[11,1],[2,1]],'tasvideos',[[19,2],[2,2],[12,5],[6,1]],'isn',[[11,1],[12,1],[4,1],[10,1],[18,2],[5,1],[7,1],[8,1],[9,1],[6,1]],'license',[[21,2]],'until',[[20,8],[6,5],[18,5],[22,6],[8,3],[9,3],[3,1],[10,4],[5,1],[7,1],[14,1],[11,6],[12,1]],'logically',[[8,1],[4,1]],'faq',[[13,1],[0,1],[19,2]],'containing',[[24,1],[4,1],[18,1],[16,1],[15,4],[5,1],[17,2],[14,3],[12,1],[6,1]],'mutual',[[2,1]],'similarly',[[22,2],[24,1],[4,1],[12,1]],'objects',[[14,3],[6,1]],'distinguish',[[22,1],[11,1],[23,1]],'processor',[[14,1]],'include',[[25,1]],'unskippable',[[6,1]],'confirms',[[22,1],[11,1]],'attack',[[12,1],[14,1]],'recharge',[[6,1]],'choosing',[[5,1],[24,1],[20,1],[6,1]],'travels',[[4,1]],'literary',[[6,1]],'taseditor_config',[[23,4]],'main',[[6,1],[22,1],[16,1],[15,2],[2,2],[9,2],[3,2],[24,1],[4,1],[10,2],[5,4],[19,2],[23,3],[14,2],[11,5],[12,6]],'shortly',[[20,1]],'markings',[[8,1]],'disappears',[[17,1],[22,2],[11,2]],'engaged',[[24,8],[18,27],[15,1],[23,3],[19,1],[12,1],[11,2]],'devote',[[4,1],[10,1]],'write',[[22,1],[18,1],[25,2],[5,1],[17,1],[7,6],[2,1],[8,2],[12,6]],'fortunately',[[10,1],[7,1]],'mass',[[22,1],[23,1],[4,4],[11,2],[6,1]],'unrelated',[[4,1]],'high',[[4,1],[10,3],[2,1],[14,1],[8,1],[11,1],[12,1]],'short',[[6,2],[22,1],[4,1],[16,2],[5,3],[8,1],[12,2],[11,1]],'repeat',[[22,1],[7,1],[8,3],[12,2]],'all',[[6,14],[14,11],[18,4],[20,7],[22,42],[16,2],[15,5],[21,1],[17,5],[2,5],[8,1],[9,5],[3,2],[24,6],[4,12],[10,6],[25,6],[5,18],[23,23],[7,13],[1,1],[13,2],[11,18],[12,18]],'lack',[[9,1]],'caption',[[3,2],[22,3],[24,1],[15,1],[5,1],[23,5],[12,1],[11,1]],'subconsciously',[[9,1]],'suffixes',[[23,1]],'releases',[[22,1],[12,2],[5,1]],'material',[[2,1]],'preceding',[[22,1],[5,1]],'grid',[[14,1]],'ones',[[22,1],[4,1],[2,1],[20,1]],'selects',[[22,1],[6,2]],'skim',[[12,1]],'platform',[[19,1],[22,1],[6,1]],'alternately',[[7,2]],'resave',[[11,1]],'ungreenzone',[[15,1]],'registerauto',[[18,3]],'lights',[[23,2]],'avoid',[[6,2],[22,1],[24,2],[14,1],[12,1],[11,2]],'range',[[22,4],[24,1],[4,1],[18,8],[5,1],[2,1],[12,4],[11,2]],'factum',[[7,1]],'amusement',[[6,1]],' the',[[15,1]],'break',[[22,1],[6,1],[4,1],[23,1],[8,1],[12,1],[11,1]],'closing',[[6,1]],'misses',[[8,1]],'duplicate',[[2,1]],'settings',[[22,4],[2,1],[3,2],[24,2],[4,1],[25,1],[5,1],[19,1],[23,9],[14,1],[1,1],[11,7],[12,1]],'manager',[[22,1],[23,9]],'session',[[4,1],[11,1]],'infinitely',[[11,1]],'several',[[6,6],[22,3],[18,3],[15,2],[17,9],[2,2],[8,1],[4,5],[10,2],[25,2],[5,3],[7,5],[12,6],[11,4]],'tremendous',[[7,1]],'enough',[[6,6],[12,5],[4,2],[20,3],[22,3],[24,1],[2,3],[7,3],[11,3],[9,1]],'give',[[22,1],[6,2]],'algorithms',[[14,2]],'keyframe',[[17,1],[22,4],[23,1]],'his',[[6,4],[22,1],[4,1],[10,2],[24,1],[2,6],[14,2],[12,2],[9,1]],'hundred',[[5,1],[11,3],[10,1],[22,1],[9,1],[6,1]],'two',[[6,6],[20,4],[18,2],[22,6],[15,2],[17,1],[2,1],[8,2],[9,1],[4,2],[10,2],[25,2],[5,2],[19,2],[23,4],[14,1],[7,3],[11,1],[12,4]],'background',[[5,2],[22,6],[15,2],[11,1]],'basics',[[2,1]],'convince',[[7,1]],'puts',[[22,2]],'box',[[12,1]],'revokes',[[8,1]],'http',[[21,1],[12,1]],'computer',[[24,1],[10,1],[14,2],[11,3],[5,1]],'spatial',[[5,2]],'skillful',[[6,1]],'minimum',[[14,1],[22,6],[7,1]],'filesystem',[[23,1]],'remaining',[[3,1],[22,1],[25,3],[8,1],[11,1],[6,2]],'disabled',[[11,13],[22,1],[10,1],[24,2],[9,3],[5,1]],'extends',[[22,1]],'disadvantage',[[9,1]],'unsuccessful',[[6,1]],'protection',[[24,1]],'difference',[[22,9],[4,1],[10,1],[5,1],[19,1],[23,3],[2,1],[14,1],[11,1]],'principal',[[7,1]],'arguments',[[22,1]],'pause',[[22,4],[4,3],[15,7],[5,3],[23,3],[11,4],[9,3]],'please',[[0,1]],'threshold',[[7,1],[2,1]],'depending',[[9,2],[6,2],[4,2],[22,3],[16,1],[25,1],[5,1],[17,2],[11,3],[12,2]],'autoscroll',[[5,1]],'getcurrentbranch',[[18,2]],'megaman',[[12,1]],'distract',[[8,1]],'partially',[[22,3],[24,1],[11,2],[12,1]],'yourself',[[6,1],[12,2],[2,1],[7,1],[9,1],[5,1]],'killing',[[9,1],[2,1]],'options',[[6,1],[12,1],[10,1],[5,1],[19,1],[7,1],[11,3],[9,1]],'rest',[[3,1],[22,2],[24,3],[11,3],[6,1]],'corresponding',[[22,11],[4,4],[16,1],[25,1],[5,5],[17,1],[12,2],[11,6]],'jumpnextmarker',[[24,1]],'purple',[[22,3],[4,1],[11,2],[5,3]],'coherent',[[2,1]],'haven',[[4,1],[10,1]],'cultivate',[[8,1]],'special',[[6,1],[22,2],[16,2],[23,1],[2,1],[14,1],[12,1],[9,1]],'fires',[[22,2],[15,3]],'compressing',[[23,1]],'watches',[[5,1],[22,2],[7,1],[6,1]],'gate',[[23,2]],'projects',[[3,1],[22,1],[24,2],[25,1],[23,1],[7,1],[2,3],[11,3],[12,5]],'seek',[[25,1],[10,2],[9,2],[5,3]],'append',[[15,1],[6,1]],'cutscene',[[6,1]],'confirm',[[9,1],[11,1]],'register',[[22,1],[12,1],[18,3]],'hints',[[3,1],[9,1]],'consistent',[[22,2],[6,1]],'adjusting',[[11,1]],'needs',[[12,3],[20,1],[4,1],[10,1],[22,4],[24,1],[5,1],[23,1],[2,2],[7,1],[11,2],[6,2]],'controlled',[[15,2],[2,1]],'drastically',[[2,1]],'paths',[[3,1]],'prudence',[[7,1]],'gaps',[[22,8],[23,1],[16,2],[11,2],[15,2]],'win',[[12,1]],'cached_timelines',[[23,1]],'detailed',[[1,1],[2,1]],'release',[[22,3],[24,1],[10,1],[15,7],[25,1],[17,3],[12,1],[6,2]],'manuals',[[19,1]],'finish',[[22,1],[4,1],[2,1],[15,1],[6,2]],'maybe',[[6,1],[5,1]],'brighter',[[5,1]],'spending',[[6,1]],'grow',[[6,2]],'integral',[[2,1]],'txt',[[24,1],[12,1]],'dispirit',[[6,1]],'dissipate',[[2,1]],'mean',[[4,1],[11,2]],'traps',[[6,1]],'removemarker',[[17,2],[18,2]],'sitting',[[22,1],[5,1]],'attach',[[19,1],[24,1],[9,1]],'implication',[[22,1]],'informational',[[10,1],[4,1],[2,1]],'capacity',[[24,3],[11,5],[23,1]],'profitable',[[7,1]],'probably',[[4,1],[2,1],[8,1],[12,3],[6,1]],'skills',[[14,1],[16,1],[21,1],[6,2]],'shiny',[[7,1]],'func',[[18,4]],'goal',[[14,1],[20,1],[10,1],[7,5],[2,2],[8,1],[9,1],[6,23]],'bool',[[25,5],[18,4],[20,1]],'evaluating',[[14,1],[22,1],[7,1]],'button',[[6,13],[22,39],[18,6],[16,10],[15,41],[17,6],[2,2],[8,1],[9,10],[24,7],[4,23],[10,11],[25,6],[5,38],[19,1],[23,6],[14,5],[7,2],[11,9],[12,25]],'calling',[[22,1],[18,2],[12,1],[25,1]],'submitinputchange',[[17,1],[22,1],[18,2],[12,1]],'whenever',[[22,1]],'idle',[[11,1]],'untouched',[[11,1]],'name',[[22,3],[11,1],[18,9],[15,1],[17,4],[3,3],[24,11],[25,1],[5,1],[19,1],[23,1],[14,1],[12,5],[6,1]],'documented',[[2,1]],'full',[[22,2],[18,2],[15,2],[9,1],[24,1],[10,2],[25,1],[5,1],[19,1],[23,4],[14,3],[11,1],[6,1]],'bug',[[19,1],[14,2]],'lua',[[22,18],[11,2],[18,5],[15,3],[17,18],[3,1],[24,1],[5,4],[23,9],[0,1],[14,5],[13,2],[20,2],[12,14]],'come',[[7,1],[2,1],[8,1],[12,1]],'vertically',[[22,1],[4,1],[6,1]],'net',[[21,1]],'supports',[[12,1],[2,2],[11,2],[5,1]],'comprehending',[[6,1]],'emphasis',[[9,1],[10,1]],'provokes',[[8,1],[10,1]],'paints',[[22,1]],'quicker',[[8,1],[2,1]],'system',[[22,4],[0,1],[14,2],[15,3],[25,1]],'component',[[22,1],[5,1]],'hidden',[[20,1],[22,1],[14,2],[12,2],[6,2]],'rise',[[6,1]],'wall',[[9,2],[6,3]],'narrows',[[10,1]],'shows',[[17,2],[22,3],[4,4],[10,2],[24,2],[23,1]],'backup',[[22,1],[8,1],[24,1]],'meant',[[22,1],[4,1]],'timers',[[12,1]],'hovering',[[22,1],[24,1]],'english',[[0,1]],'glitch',[[14,1],[6,1]],'discoveries',[[6,2]],'commands',[[22,3],[24,4],[18,1],[15,3],[23,7],[19,2],[5,1],[25,3]],'bookmark',[[11,18],[20,5],[22,62],[16,3],[15,17],[17,13],[8,9],[9,5],[24,6],[10,3],[5,52],[19,3],[23,7],[14,3],[12,1],[6,7]],'adheres',[[8,1]],'table',[[3,1],[22,2],[4,2],[18,6],[15,1],[23,1],[14,1]],'meaningless',[[25,1],[14,1]],'saturated',[[22,1]],'flashings',[[23,4]],'compact',[[22,2],[25,1],[12,14],[23,1]],'nowadays',[[14,1]],'listbox',[[24,3],[11,1]],'edition',[[22,1],[11,1],[18,1],[6,1],[15,1],[2,1],[8,1],[9,1],[3,1],[25,1],[7,1],[1,1],[13,1],[16,1],[21,1],[17,1],[24,1],[4,1],[10,1],[5,1],[19,1],[0,1],[23,1],[14,1],[12,1],[20,1]],'preferences',[[3,1]],'economy',[[11,1]],'section',[[6,1],[22,3],[16,1],[15,1],[21,1],[17,1],[2,2],[4,2],[25,2],[5,18],[7,1],[14,1],[12,1],[11,1]],'objectivity',[[9,1],[2,1]],'deploying',[[23,1]],'represented',[[22,1],[25,2]],'assistance',[[0,1]],'shades',[[22,1],[11,1]],'disclose',[[22,1]],'rolled',[[22,2],[15,1]],'factors',[[12,2],[20,2],[10,3],[5,1],[7,4],[8,1],[9,2],[6,23]],'decompression',[[23,4]],'letters',[[4,3]],'shifts',[[22,2]],'famicom',[[15,2],[25,1]],'abused',[[14,1]],'tortoisesvn',[[21,1]],'animates',[[23,1]],'where',[[6,8],[20,5],[18,2],[22,5],[16,5],[15,4],[17,14],[9,6],[24,1],[4,4],[10,4],[25,1],[5,10],[19,1],[7,1],[14,1],[11,4],[12,7]],'scrollbar',[[22,1],[4,1],[16,4],[15,1]],'standards',[[12,1]],'unparalleled',[[2,1]],'save',[[20,4],[22,4],[15,14],[17,1],[2,2],[8,3],[9,3],[24,16],[10,2],[25,4],[5,4],[19,2],[23,8],[14,2],[7,3],[12,16],[11,9]],'uploading',[[2,1]],'insistent',[[8,1],[10,1]],'yyy',[[25,2]],'worked',[[10,1]],'retrieved',[[22,1]],'gamepad',[[15,3],[5,3],[17,3],[2,2],[14,3],[11,10],[6,1]],'data',[[6,1],[20,1],[18,1],[22,51],[16,9],[15,1],[17,7],[2,1],[8,1],[9,1],[3,1],[24,6],[4,4],[25,25],[5,11],[19,1],[23,51],[14,12],[7,3],[11,9],[12,10]],'f10',[[24,1],[15,2],[5,3],[17,3],[7,1],[8,1],[11,3]],'track',[[22,3],[20,1],[14,1]],'interface',[[3,3],[22,3],[4,1],[23,6],[19,1],[0,1],[2,3],[1,1],[14,1],[11,1]],'macro',[[22,3],[12,1]],'improving',[[9,1],[6,1]],'pixel',[[22,2]],'caches',[[23,1]],'affects',[[7,1],[16,1],[11,1],[6,1]],'race',[[14,1]],'figuring',[[2,1]],'language',[[2,1],[14,1],[12,2],[5,1]],'resyncing',[[10,1]],'fear',[[9,1]],'unsatisfactory',[[7,1]],'literature',[[12,1]],'bullet',[[9,4],[6,1]],'question',[[6,1],[24,1],[2,1],[7,2],[15,1],[5,1]],'facts',[[2,1]],'started',[[22,3],[9,1],[11,1]],'stretching',[[24,1]],'bit2',[[25,2]],'fds',[[24,2],[18,2],[15,4],[25,2]],'minor',[[22,1],[23,1],[7,1],[6,1]],'created',[[22,5],[11,3],[18,2],[6,1],[15,1],[2,2],[8,2],[9,2],[3,1],[25,2],[7,4],[1,1],[13,1],[16,1],[21,1],[17,32],[24,1],[4,1],[10,1],[5,4],[19,1],[0,1],[23,1],[14,4],[12,5],[20,1]],'craftily',[[2,1]],'side',[[22,7],[24,2],[18,1],[15,7],[25,2],[7,1],[6,2]],'monstrous',[[5,1]],'subdivide',[[6,1]],'scenarios',[[5,1]],'details',[[22,6],[24,1],[4,1],[21,2],[15,1],[19,1],[0,1],[20,3],[12,2]],'freely',[[11,1],[15,1]],'account',[[22,1]],'pops',[[9,1],[5,1]],'beginning',[[6,14],[22,11],[16,21],[15,6],[8,8],[9,6],[24,2],[4,3],[10,5],[25,3],[5,7],[23,3],[7,4],[14,1],[11,1],[12,8]],'critic',[[6,1]],'relieved',[[12,1]],'bookmark2',[[17,1]],'number',[[6,3],[20,5],[18,21],[22,60],[16,2],[15,7],[17,21],[2,1],[8,1],[9,2],[3,1],[24,2],[4,10],[10,1],[25,10],[5,12],[19,2],[23,1],[14,1],[11,6],[12,2]],'%03d',[[25,2]],'knows',[[4,1]],'adding',[[22,1],[4,1],[14,1],[12,1],[23,1]],'safely',[[24,1],[9,1]],'added',[[3,1],[22,3],[4,1],[25,4],[17,12],[19,1],[12,2]],'indulge',[[6,1]],'allowed',[[6,2]],'automatically',[[20,2],[22,13],[16,4],[15,3],[17,1],[9,2],[3,1],[24,1],[4,6],[10,2],[5,6],[23,1],[7,2],[14,2],[12,3],[11,4]],'trail',[[4,2]],'tutorial',[[19,1],[2,1]],'doc',[[19,1],[21,1],[9,1]],'mention',[[22,1]],'counter',[[22,14],[18,1],[15,4],[2,3],[14,1],[11,1],[6,6]],'selection_table',[[12,3]],'boolean',[[22,1]],'pushing',[[14,1]],'always',[[6,6],[20,3],[22,12],[16,2],[15,2],[2,2],[8,2],[9,3],[24,4],[4,3],[10,1],[25,5],[5,5],[23,2],[14,1],[7,6],[11,4],[12,3]],'mostly',[[3,1],[19,1],[7,1],[11,1],[6,1]],'imply',[[4,1]],'excessively',[[6,1]],'learning',[[3,1],[10,1],[2,2],[1,1]],'almost',[[22,3],[4,3],[10,1],[7,3],[2,2],[14,1],[9,1],[11,1]],'records',[[6,1],[22,2],[4,1],[25,2],[5,1],[17,1],[7,2],[12,1],[11,1]],'respective',[[22,2],[15,1],[5,1],[23,3],[25,1],[14,2],[20,1],[11,3]],'seconds',[[4,1],[7,1],[10,1],[14,1],[11,1],[6,1]],'significantly',[[22,2],[24,1],[11,2]],'codebase',[[23,1]],'today',[[12,1]],'transpose',[[24,1],[16,1],[15,1]],'ability',[[22,8],[24,1],[7,1],[2,2],[6,1]],'delivers',[[12,1]],'sequence',[[6,3],[22,6],[4,2],[10,1],[18,1],[16,1],[17,2],[7,2],[14,7],[12,12],[11,2]],'players',[[12,2],[4,1],[5,1],[19,1],[2,1],[7,2],[14,1],[11,1],[6,2]],'chapter',[[3,3],[12,1],[10,1],[16,1],[15,2],[5,1],[2,1],[7,1],[11,5],[6,2]],'workspace',[[3,1],[4,1]],'teleporter',[[6,1]],'there',[[6,6],[20,3],[18,5],[22,21],[16,1],[15,3],[17,8],[2,3],[8,5],[9,3],[3,3],[4,9],[10,7],[25,4],[5,5],[19,4],[23,5],[14,1],[7,6],[11,9],[12,8]],'platforms',[[22,4],[21,1],[24,1]],'specific',[[3,1],[20,1],[18,1],[22,1],[16,2],[23,3],[17,1],[14,1],[12,1],[6,2]],'auto',[[22,6],[18,6],[15,2],[2,3],[8,1],[9,1],[3,1],[24,2],[4,1],[10,2],[5,3],[23,3],[12,2],[11,2]],'explain',[[19,1],[2,1]],'logical',[[12,1],[4,1],[2,1],[9,2],[6,2]],'along',[[22,3],[4,1],[5,1],[7,1],[8,1],[12,1],[11,3]],'screenshots',[[15,1],[22,7],[20,3],[11,6]],'rooms',[[6,1]],'peculiarity',[[6,1]],'luck',[[10,1],[14,3],[9,1],[20,1]],'fm3s',[[25,1]],'flag',[[22,1]],'speed',[[22,5],[6,9],[15,9],[2,1],[8,2],[9,3],[24,1],[10,2],[5,5],[23,1],[14,9],[7,2],[11,4],[12,3]],'urging',[[3,1]],'view',[[3,1],[22,3],[24,2],[16,2],[5,7],[19,2],[2,2],[14,1],[11,9]],'newlines',[[25,2]],'updating',[[23,1],[14,1]],'slowing',[[14,1],[2,1]],'excluding',[[22,1]],'pair',[[22,1],[20,1]],'fcexp',[[25,1]],'dissection',[[1,1]],'obligatory',[[11,1]],'getinput',[[12,1],[18,2]],'expanded',[[22,1]],'unpaused',[[22,1],[18,2],[7,1],[15,1],[5,1]],'boost',[[14,1]],'emulating',[[22,2],[16,1],[11,1]],'real',[[12,1],[14,5],[4,3],[10,2],[22,5],[15,1],[5,1],[2,1],[7,4],[8,1],[11,4],[6,3]],'cleaned',[[11,1]],'500kb',[[12,1]],'forget',[[4,1],[18,1],[8,1],[9,1],[6,2]],'selecting',[[22,2],[24,1],[18,1],[12,1],[15,2]],'building',[[23,1]],'bookmark7',[[17,1]],'continuum',[[2,1]],'glance',[[3,1],[4,1],[9,2]],'spontaneously',[[6,1]],'hacks',[[2,1]],'cases',[[11,4],[12,5],[10,2],[22,7],[24,1],[5,1],[23,1],[2,1],[7,2],[14,1],[9,1],[6,3]],'pastel',[[22,2]],'unsystematic',[[2,1]],'pressing',[[6,1],[12,4],[4,1],[10,2],[22,3],[24,1],[15,7],[5,6],[23,1],[14,2],[11,6],[9,7]],'early',[[22,1],[10,1],[2,1],[6,2]],'navigating',[[10,1],[7,3],[8,1],[16,1]],'love',[[7,1]],'effective',[[4,1],[19,1],[7,1],[14,1],[8,2],[12,2],[6,1]],'fills',[[22,1]],'share',[[12,7],[2,1]],'storage',[[14,3]],'pauses',[[3,1],[18,2],[20,1],[5,1]],'field',[[22,6],[4,6],[16,2],[15,5],[5,1],[17,4],[23,6],[25,8],[11,2]],'backtrack',[[11,1]],'semiautomatic',[[14,1],[10,5],[7,1]],'well',[[9,1],[12,1],[20,1],[22,3],[21,1],[5,3],[17,2],[23,1],[2,2],[8,1],[11,2],[6,5]],'scrolled',[[22,2],[4,1]],'under',[[22,16],[24,2],[4,1],[18,1],[21,2],[15,1],[5,2],[11,1]],'overlapping',[[15,1]],'moderately',[[17,7]],'indicated',[[22,2]],'cooling',[[11,1]],'lower',[[22,5],[4,5],[16,2],[15,3],[5,3],[17,1],[23,4],[2,1],[11,2]],'saving',[[22,7],[6,1],[15,1],[17,1],[2,1],[9,1],[3,2],[24,7],[25,1],[5,3],[23,6],[7,1],[11,9],[12,8]],'measured',[[14,1]],'subclasses',[[23,1]],'authorship',[[6,1],[12,1],[2,1]],'did',[[22,2],[11,1],[14,1]],'unregistered',[[6,1]],'wrong',[[5,1],[10,1],[7,1],[8,1],[12,1],[6,2]],'optimize',[[8,1]],'hands',[[11,1],[5,1]],'midi',[[14,1]],'mariox',[[12,3]],'hide',[[5,1],[22,3],[24,1],[15,3],[12,1]],'clicked',[[22,2],[5,1]],'capabilities',[[22,1]],'versions',[[22,2],[24,1],[5,2],[19,1],[2,2],[7,1],[6,2]],'ups',[[22,3]],'pausing',[[9,1]],'thinking',[[2,3],[8,1],[9,1],[6,2]],'occurring',[[22,1],[10,1]],'addition',[[22,10],[4,1],[5,2],[2,4],[7,1],[8,1],[11,1],[20,1]],'non',[[22,1],[15,1],[5,2],[17,2],[2,2],[7,1],[12,2],[6,1]],'jumped',[[6,2]],'returns',[[22,5],[23,1],[18,35],[7,2],[5,1]],'trackers',[[14,1]],'closer',[[22,1],[7,1],[14,1],[6,2]],'nonlinear',[[10,2],[7,1],[14,2],[8,1],[9,3]],'ideally',[[16,1],[10,1]],'start',[[6,5],[20,1],[18,2],[22,4],[15,2],[2,1],[8,1],[9,3],[24,3],[4,2],[10,11],[25,3],[5,2],[19,1],[23,3],[7,3],[11,3],[12,8]],'handle',[[24,1],[18,1],[5,1]],'proofing',[[23,1],[0,1],[24,2],[21,1],[11,1],[15,1]],'feedback',[[10,2],[7,2],[8,2],[9,1]],'bored',[[10,1],[12,1]],'analyze',[[6,1],[12,1],[2,1],[9,1],[5,1]],'jobs',[[22,2]],'layer',[[23,1]],'entering',[[7,1],[8,1],[15,1],[5,1]],'methodical',[[6,1],[23,1],[2,1]],'gradual',[[11,1],[23,2]],'difficult',[[22,1],[7,2],[2,1],[6,4]],'accelerator',[[23,1],[15,3],[5,1]],'registermanual',[[12,2],[18,4]],'remember',[[6,1],[22,2],[4,2],[16,1],[5,1],[7,1],[12,3],[11,1]],'mushroom',[[6,1]],'himself',[[6,1],[2,1]],'rewatching',[[8,1]],'complicates',[[8,1]],'memory',[[20,9],[6,5],[22,6],[16,1],[15,1],[8,2],[9,1],[24,2],[10,1],[5,1],[23,2],[7,1],[14,2],[11,9],[12,8]],'reassign',[[11,2]],'solution',[[12,2],[7,1],[14,6],[9,1],[6,1]],'selectiox',[[25,1]],'some',[[6,15],[20,2],[18,3],[22,12],[16,3],[15,5],[21,1],[17,25],[2,8],[8,7],[9,2],[24,2],[4,5],[10,5],[5,11],[19,1],[23,3],[14,7],[13,1],[7,4],[11,8],[12,11]],'briefly',[[17,2]],'overlooked',[[6,2]],'kilobytes',[[11,1]],'accept',[[10,2],[5,1]],'hand',[[24,1],[10,1],[4,1],[15,2],[6,1]],'initialize',[[12,2]],'hotkey',[[9,3],[22,5],[4,1],[24,1],[16,3],[15,9],[5,8],[17,3],[8,1],[11,8],[12,1]],'other',[[6,4],[20,1],[18,2],[22,17],[16,6],[15,7],[17,5],[2,2],[8,3],[9,1],[3,2],[24,3],[4,4],[10,1],[25,1],[5,12],[19,5],[23,2],[14,2],[7,1],[11,2],[12,5]],'reviews',[[13,1]],'like',[[6,9],[22,6],[18,2],[16,3],[21,1],[2,2],[9,3],[3,2],[24,2],[4,2],[10,1],[5,4],[23,2],[7,2],[14,1],[11,4],[12,6]],'bound',[[16,1]],'interest',[[22,3],[4,1],[7,1],[10,1],[8,1]],'red',[[22,6],[4,4],[15,1],[5,4],[19,1],[14,1],[12,1],[11,6]],'rendered',[[5,1]],'given',[[22,5],[18,33],[16,3],[15,1],[23,3],[25,1],[7,2],[2,1],[14,2],[11,2],[12,1]],'deletion',[[18,1],[23,1]],'scenario',[[2,1]],'structure',[[22,1],[6,2]],'retry',[[7,1],[6,1]],'gamers',[[7,1]],'topical',[[12,1]],'met',[[6,2]],'needed',[[6,2],[20,1],[22,5],[16,3],[15,3],[8,4],[9,2],[4,2],[10,1],[25,1],[5,4],[19,1],[23,2],[7,4],[14,2],[11,5],[12,6]],'better',[[6,9],[20,5],[16,1],[2,2],[8,4],[9,6],[3,1],[10,3],[5,2],[14,3],[7,2],[11,2],[12,2]],'postponed',[[22,3],[12,1],[6,1]],'fail',[[8,1],[7,1]],'correctly',[[11,2],[7,1]],'levels',[[3,1],[12,1],[22,2],[24,1],[5,1],[2,2],[8,1],[11,4],[6,5]],'intricate',[[6,1]],'produced',[[9,1]],'closes',[[24,1]],'notes',[[3,1],[12,12],[4,3],[22,4],[15,1],[5,2],[23,7],[0,1],[14,1],[11,6],[6,2]],'edits',[[22,1],[23,1],[4,1],[2,1],[11,3],[5,1]],'supersaturated',[[6,1]],'terms',[[3,1],[6,2],[22,1],[7,1],[13,1],[14,3],[12,1],[9,1]],'confidently',[[7,1]],'differently',[[25,1],[5,1]],'sprouted',[[6,1]],'its',[[6,7],[22,12],[18,1],[16,3],[15,2],[17,4],[2,3],[9,4],[3,1],[24,4],[4,2],[10,2],[25,3],[5,9],[19,1],[23,2],[7,4],[14,5],[11,10],[12,6]],'viewing',[[22,2]]];window.bSearchDataLoaded=true; \ No newline at end of file diff --git a/web/help/taseditor/js/hndse.min.js b/web/help/taseditor/js/hndse.min.js new file mode 100644 index 00000000..890ceed6 --- /dev/null +++ b/web/help/taseditor/js/hndse.min.js @@ -0,0 +1,6 @@ +"use strict";/*! + * HND JavaScript search engine + * Copyright (C) IBE Software - All rights reserved. + * Can only be used in documentation generated by HelpNDoc: http://www.helpndoc.com + */ +var Score;!function(r){r[r.TopicNumber=0]="TopicNumber",r[r.TopicScore=1]="TopicScore"}(Score||(Score={}));var HndJsSeWordList=function(){function r(){this.words=[]}return r.prototype.AddWord=function(r){this.words.push(r.toLowerCase())},r.prototype.Clear=function(){this.words=[]},r.prototype.Count=function(){return this.words.length},r.prototype.FindExact=function(r){return r=r.toLowerCase(),this.words.indexOf(r)},r.prototype.FindPartial=function(r){r=r.toLowerCase();for(var o=0;o-1?o.scores[i][Score.TopicScore]=o.scores[i][Score.TopicScore]+t:o.scores.push([e,t])})},r.prototype.Clear=function(){this.scores=[]},r.prototype.ExcludeTopics=function(r){var o=this;if(!r||!r.forEach)return void console.error("Invalid ExcludeTopics call");r.forEach(function(r){if(!r||!Array.isArray(r)||2!==r.length)return void console.error("Invalid data in ExcludeTopics");var e=r[Score.TopicNumber];if("number"!=typeof e||e<0)return void console.error("Invalid topic data in ExcludeTopics");var t=o.FindTopicIndex(e);t>-1&&o.scores.splice(t,1)})},r.prototype.SortByScore=function(){this.scores.sort(function(r,o){return r[Score.TopicScore]>o[Score.TopicScore]?-1:r[Score.TopicScore]0&&'"'===t[0];)t=t.substr(1);for(;t.length>0&&'"'===t[t.length-1];)t=t.substr(0,t.length-1);switch(i){case"-":this.inputWordsExcluded.AddWord(t);break;case"+":this.inputWordsIncluded.AddWord(t);break;default:this.inputWordsMandatory.AddWord(t)}}}},r.prototype.PerformSearch=function(r){var o=this;if(this.resultScoreIncluded=new HndJsSeResultScore,this.resultScoreMandatory=new HndJsSeResultScore,this.resultScoreExcluded=new HndJsSeResultScore,!r||!r.length)return console.error("Invalid word list data"),[];var e;r.forEach(function(r){if("string"==typeof r)e=r.trim().toLowerCase();else{if(!Array.isArray(r))return void console.error("Invalid element in word list data:",r);if(""==e)return void console.warn("Empty word should not be included in list");-1!==o.inputWordsIncluded.FindPartial(e)&&o.resultScoreIncluded.AddTopics(r),-1!==o.inputWordsMandatory.FindPartial(e)&&o.resultScoreMandatory.AddTopics(r),-1!==o.inputWordsExcluded.FindPartial(e)&&o.resultScoreExcluded.AddTopics(r)}});var t=this.resultScoreIncluded;return t.AddTopics(this.resultScoreMandatory.scores),t.ExcludeTopics(this.resultScoreExcluded.scores),t.SortByScore(),t.scores},r}(); \ No newline at end of file diff --git a/web/help/taseditor/js/polyfill.object.min.js b/web/help/taseditor/js/polyfill.object.min.js new file mode 100644 index 00000000..5b0e41ba --- /dev/null +++ b/web/help/taseditor/js/polyfill.object.min.js @@ -0,0 +1 @@ +"use strict";"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(e){for(var r=[],t=1;tli>a:focus,.dropdown-menu>li>a:hover{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x;background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x;background-color:#2e6da4}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/css/bootstrap.min.css b/web/help/taseditor/vendors/bootstrap-3.4.1/css/bootstrap.min.css new file mode 100644 index 00000000..455de954 --- /dev/null +++ b/web/help/taseditor/vendors/bootstrap-3.4.1/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:"Glyphicons Halflings";src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),url(../fonts/glyphicons-halflings-regular.woff2) format("woff2"),url(../fonts/glyphicons-halflings-regular.woff) format("woff"),url(../fonts/glyphicons-halflings-regular.ttf) format("truetype"),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:"Glyphicons Halflings";font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-right:-15px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/css/ie10-viewport-bug-workaround.css b/web/help/taseditor/vendors/bootstrap-3.4.1/css/ie10-viewport-bug-workaround.css new file mode 100644 index 00000000..8f7d32b0 --- /dev/null +++ b/web/help/taseditor/vendors/bootstrap-3.4.1/css/ie10-viewport-bug-workaround.css @@ -0,0 +1,15 @@ +/*! + * IE10 viewport hack for Surface/desktop Windows 8 bug + * Copyright 2014-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/* + * See the Getting Started docs for more information: + * http://getbootstrap.com/getting-started/#support-ie10-width + */ +@-webkit-viewport { width: device-width; } +@-moz-viewport { width: device-width; } +@-ms-viewport { width: device-width; } +@-o-viewport { width: device-width; } +@viewport { width: device-width; } \ No newline at end of file diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 00000000..b93a4953 Binary files /dev/null and b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot differ diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..94fb5490 --- /dev/null +++ b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..1413fc60 Binary files /dev/null and b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf differ diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..9e612858 Binary files /dev/null and b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff differ diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 00000000..64539b54 Binary files /dev/null and b/web/help/taseditor/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/web/help/taseditor/vendors/bootstrap-3.4.1/js/bootstrap.min.js b/web/help/taseditor/vendors/bootstrap-3.4.1/js/bootstrap.min.js new file mode 100644 index 00000000..eb0a8b41 --- /dev/null +++ b/web/help/taseditor/vendors/bootstrap-3.4.1/js/bootstrap.min.js @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");!function(t){"use strict";var e=jQuery.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||3this.$items.length-1||t<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(idocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},s.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},s.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0},sanitize:!0,sanitizeFn:null,whiteList:t},m.prototype.init=function(t,e,i){if(this.enabled=!0,this.type=t,this.$element=g(e),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&g(document).find(g.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var o=this.options.trigger.split(" "),n=o.length;n--;){var s=o[n];if("click"==s)this.$element.on("click."+this.type,this.options.selector,g.proxy(this.toggle,this));else if("manual"!=s){var a="hover"==s?"mouseenter":"focusin",r="hover"==s?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,g.proxy(this.enter,this)),this.$element.on(r+"."+this.type,this.options.selector,g.proxy(this.leave,this))}}this.options.selector?this._options=g.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},m.prototype.getDefaults=function(){return m.DEFAULTS},m.prototype.getOptions=function(t){var e=this.$element.data();for(var i in e)e.hasOwnProperty(i)&&-1!==g.inArray(i,o)&&delete e[i];return(t=g.extend({},this.getDefaults(),e,t)).delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t.sanitize&&(t.template=n(t.template,t.whiteList,t.sanitizeFn)),t},m.prototype.getDelegateOptions=function(){var i={},o=this.getDefaults();return this._options&&g.each(this._options,function(t,e){o[t]!=e&&(i[t]=e)}),i},m.prototype.enter=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusin"==t.type?"focus":"hover"]=!0),e.tip().hasClass("in")||"in"==e.hoverState)e.hoverState="in";else{if(clearTimeout(e.timeout),e.hoverState="in",!e.options.delay||!e.options.delay.show)return e.show();e.timeout=setTimeout(function(){"in"==e.hoverState&&e.show()},e.options.delay.show)}},m.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},m.prototype.leave=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusout"==t.type?"focus":"hover"]=!1),!e.isInStateTrue()){if(clearTimeout(e.timeout),e.hoverState="out",!e.options.delay||!e.options.delay.hide)return e.hide();e.timeout=setTimeout(function(){"out"==e.hoverState&&e.hide()},e.options.delay.hide)}},m.prototype.show=function(){var t=g.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(t);var e=g.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(t.isDefaultPrevented()||!e)return;var i=this,o=this.tip(),n=this.getUID(this.type);this.setContent(),o.attr("id",n),this.$element.attr("aria-describedby",n),this.options.animation&&o.addClass("fade");var s="function"==typeof this.options.placement?this.options.placement.call(this,o[0],this.$element[0]):this.options.placement,a=/\s?auto?\s?/i,r=a.test(s);r&&(s=s.replace(a,"")||"top"),o.detach().css({top:0,left:0,display:"block"}).addClass(s).data("bs."+this.type,this),this.options.container?o.appendTo(g(document).find(this.options.container)):o.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var l=this.getPosition(),h=o[0].offsetWidth,d=o[0].offsetHeight;if(r){var p=s,c=this.getPosition(this.$viewport);s="bottom"==s&&l.bottom+d>c.bottom?"top":"top"==s&&l.top-dc.width?"left":"left"==s&&l.left-ha.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.right&&(n.left=a.left+a.width-d)}return n},m.prototype.getTitle=function(){var t=this.$element,e=this.options;return t.attr("data-original-title")||("function"==typeof e.title?e.title.call(t[0]):e.title)},m.prototype.getUID=function(t){for(;t+=~~(1e6*Math.random()),document.getElementById(t););return t},m.prototype.tip=function(){if(!this.$tip&&(this.$tip=g(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},m.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},m.prototype.enable=function(){this.enabled=!0},m.prototype.disable=function(){this.enabled=!1},m.prototype.toggleEnabled=function(){this.enabled=!this.enabled},m.prototype.toggle=function(t){var e=this;t&&((e=g(t.currentTarget).data("bs."+this.type))||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e))),t?(e.inState.click=!e.inState.click,e.isInStateTrue()?e.enter(e):e.leave(e)):e.tip().hasClass("in")?e.leave(e):e.enter(e)},m.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})},m.prototype.sanitizeHtml=function(t){return n(t,this.options.whiteList,this.options.sanitizeFn)};var e=g.fn.tooltip;g.fn.tooltip=function i(o){return this.each(function(){var t=g(this),e=t.data("bs.tooltip"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.tooltip",e=new m(this,i)),"string"==typeof o&&e[o]())})},g.fn.tooltip.Constructor=m,g.fn.tooltip.noConflict=function(){return g.fn.tooltip=e,this}}(jQuery),function(n){"use strict";var s=function(t,e){this.init("popover",t,e)};if(!n.fn.tooltip)throw new Error("Popover requires tooltip.js");s.VERSION="3.4.1",s.DEFAULTS=n.extend({},n.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),((s.prototype=n.extend({},n.fn.tooltip.Constructor.prototype)).constructor=s).prototype.getDefaults=function(){return s.DEFAULTS},s.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();if(this.options.html){var o=typeof i;this.options.sanitize&&(e=this.sanitizeHtml(e),"string"===o&&(i=this.sanitizeHtml(i))),t.find(".popover-title").html(e),t.find(".popover-content").children().detach().end()["string"===o?"html":"append"](i)}else t.find(".popover-title").text(e),t.find(".popover-content").children().detach().end().text(i);t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},s.prototype.hasContent=function(){return this.getTitle()||this.getContent()},s.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},s.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var t=n.fn.popover;n.fn.popover=function e(o){return this.each(function(){var t=n(this),e=t.data("bs.popover"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.popover",e=new s(this,i)),"string"==typeof o&&e[o]())})},n.fn.popover.Constructor=s,n.fn.popover.noConflict=function(){return n.fn.popover=t,this}}(jQuery),function(s){"use strict";function n(t,e){this.$body=s(document.body),this.$scrollElement=s(t).is(document.body)?s(window):s(t),this.options=s.extend({},n.DEFAULTS,e),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",s.proxy(this.process,this)),this.refresh(),this.process()}function e(o){return this.each(function(){var t=s(this),e=t.data("bs.scrollspy"),i="object"==typeof o&&o;e||t.data("bs.scrollspy",e=new n(this,i)),"string"==typeof o&&e[o]()})}n.VERSION="3.4.1",n.DEFAULTS={offset:10},n.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},n.prototype.refresh=function(){var t=this,o="offset",n=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),s.isWindow(this.$scrollElement[0])||(o="position",n=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var t=s(this),e=t.data("target")||t.attr("href"),i=/^#./.test(e)&&s(e);return i&&i.length&&i.is(":visible")&&[[i[o]().top+n,e]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},n.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),o<=e)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(n[t+1]===undefined||e .active"),n=i&&r.support.transition&&(o.length&&o.hasClass("fade")||!!e.find("> .fade").length);function s(){o.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),t.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),n?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu").length&&t.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),i&&i()}o.length&&n?o.one("bsTransitionEnd",s).emulateTransitionEnd(a.TRANSITION_DURATION):s(),o.removeClass("in")};var t=r.fn.tab;r.fn.tab=e,r.fn.tab.Constructor=a,r.fn.tab.noConflict=function(){return r.fn.tab=t,this};var i=function(t){t.preventDefault(),e.call(r(this),"show")};r(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',i).on("click.bs.tab.data-api",'[data-toggle="pill"]',i)}(jQuery),function(l){"use strict";var h=function(t,e){this.options=l.extend({},h.DEFAULTS,e);var i=this.options.target===h.DEFAULTS.target?l(this.options.target):l(document).find(this.options.target);this.$target=i.on("scroll.bs.affix.data-api",l.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",l.proxy(this.checkPositionWithEventLoop,this)),this.$element=l(t),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};function i(o){return this.each(function(){var t=l(this),e=t.data("bs.affix"),i="object"==typeof o&&o;e||t.data("bs.affix",e=new h(this,i)),"string"==typeof o&&e[o]()})}h.VERSION="3.4.1",h.RESET="affix affix-top affix-bottom",h.DEFAULTS={offset:0,target:window},h.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return ns.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t,n){n=n||{},Object.assign(this,o.options,n),this.classes=Object.assign({},o.options.classes,n.classes),this.elem=t,this.tolerance=function(t){return t===Object(t)?t:{down:t,up:t}}(this.tolerance),this.initialised=!1,this.frozen=!1}return o.prototype={constructor:o,init:function(){return o.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},o.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},o.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),o}); \ No newline at end of file diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/0.png b/web/help/taseditor/vendors/helpndoc-5/icons/0.png new file mode 100644 index 00000000..0189cda7 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/0.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/1.png b/web/help/taseditor/vendors/helpndoc-5/icons/1.png new file mode 100644 index 00000000..01335b02 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/1.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/10.png b/web/help/taseditor/vendors/helpndoc-5/icons/10.png new file mode 100644 index 00000000..86c1b70c Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/10.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/11.png b/web/help/taseditor/vendors/helpndoc-5/icons/11.png new file mode 100644 index 00000000..60da1797 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/11.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/12.png b/web/help/taseditor/vendors/helpndoc-5/icons/12.png new file mode 100644 index 00000000..7977cad2 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/12.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/13.png b/web/help/taseditor/vendors/helpndoc-5/icons/13.png new file mode 100644 index 00000000..2d6b99eb Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/13.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/14.png b/web/help/taseditor/vendors/helpndoc-5/icons/14.png new file mode 100644 index 00000000..c6150b5f Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/14.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/15.png b/web/help/taseditor/vendors/helpndoc-5/icons/15.png new file mode 100644 index 00000000..58f205ff Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/15.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/16.png b/web/help/taseditor/vendors/helpndoc-5/icons/16.png new file mode 100644 index 00000000..746f6c4e Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/16.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/17.png b/web/help/taseditor/vendors/helpndoc-5/icons/17.png new file mode 100644 index 00000000..e450e6b6 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/17.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/18.png b/web/help/taseditor/vendors/helpndoc-5/icons/18.png new file mode 100644 index 00000000..fae8d066 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/18.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/19.png b/web/help/taseditor/vendors/helpndoc-5/icons/19.png new file mode 100644 index 00000000..557aa37b Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/19.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/2.png b/web/help/taseditor/vendors/helpndoc-5/icons/2.png new file mode 100644 index 00000000..38870794 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/2.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/20.png b/web/help/taseditor/vendors/helpndoc-5/icons/20.png new file mode 100644 index 00000000..cb6845bc Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/20.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/21.png b/web/help/taseditor/vendors/helpndoc-5/icons/21.png new file mode 100644 index 00000000..bfb11c91 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/21.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/22.png b/web/help/taseditor/vendors/helpndoc-5/icons/22.png new file mode 100644 index 00000000..17ed9c5b Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/22.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/23.png b/web/help/taseditor/vendors/helpndoc-5/icons/23.png new file mode 100644 index 00000000..1c4a863b Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/23.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/24.png b/web/help/taseditor/vendors/helpndoc-5/icons/24.png new file mode 100644 index 00000000..e91b518c Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/24.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/25.png b/web/help/taseditor/vendors/helpndoc-5/icons/25.png new file mode 100644 index 00000000..00d2d5d3 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/25.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/26.png b/web/help/taseditor/vendors/helpndoc-5/icons/26.png new file mode 100644 index 00000000..4952af63 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/26.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/27.png b/web/help/taseditor/vendors/helpndoc-5/icons/27.png new file mode 100644 index 00000000..a61fe9bd Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/27.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/28.png b/web/help/taseditor/vendors/helpndoc-5/icons/28.png new file mode 100644 index 00000000..52160f07 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/28.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/29.png b/web/help/taseditor/vendors/helpndoc-5/icons/29.png new file mode 100644 index 00000000..06aa97cb Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/29.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/3.png b/web/help/taseditor/vendors/helpndoc-5/icons/3.png new file mode 100644 index 00000000..b1c94138 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/3.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/30.png b/web/help/taseditor/vendors/helpndoc-5/icons/30.png new file mode 100644 index 00000000..7b52276d Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/30.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/31.png b/web/help/taseditor/vendors/helpndoc-5/icons/31.png new file mode 100644 index 00000000..02283dbb Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/31.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/32.png b/web/help/taseditor/vendors/helpndoc-5/icons/32.png new file mode 100644 index 00000000..875843c5 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/32.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/33.png b/web/help/taseditor/vendors/helpndoc-5/icons/33.png new file mode 100644 index 00000000..d64f1371 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/33.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/34.png b/web/help/taseditor/vendors/helpndoc-5/icons/34.png new file mode 100644 index 00000000..a6d94c5d Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/34.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/35.png b/web/help/taseditor/vendors/helpndoc-5/icons/35.png new file mode 100644 index 00000000..dfc87bf7 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/35.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/36.png b/web/help/taseditor/vendors/helpndoc-5/icons/36.png new file mode 100644 index 00000000..ce6235b2 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/36.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/37.png b/web/help/taseditor/vendors/helpndoc-5/icons/37.png new file mode 100644 index 00000000..01203304 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/37.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/38.png b/web/help/taseditor/vendors/helpndoc-5/icons/38.png new file mode 100644 index 00000000..5334faee Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/38.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/39.png b/web/help/taseditor/vendors/helpndoc-5/icons/39.png new file mode 100644 index 00000000..06e446b8 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/39.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/4.png b/web/help/taseditor/vendors/helpndoc-5/icons/4.png new file mode 100644 index 00000000..6e5cfc09 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/4.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/40.png b/web/help/taseditor/vendors/helpndoc-5/icons/40.png new file mode 100644 index 00000000..6d744dbe Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/40.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/41.png b/web/help/taseditor/vendors/helpndoc-5/icons/41.png new file mode 100644 index 00000000..476edf46 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/41.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/5.png b/web/help/taseditor/vendors/helpndoc-5/icons/5.png new file mode 100644 index 00000000..1df634fe Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/5.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/6.png b/web/help/taseditor/vendors/helpndoc-5/icons/6.png new file mode 100644 index 00000000..947d9c40 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/6.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/7.png b/web/help/taseditor/vendors/helpndoc-5/icons/7.png new file mode 100644 index 00000000..a3628866 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/7.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/8.png b/web/help/taseditor/vendors/helpndoc-5/icons/8.png new file mode 100644 index 00000000..5bcd3eca Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/8.png differ diff --git a/web/help/taseditor/vendors/helpndoc-5/icons/9.png b/web/help/taseditor/vendors/helpndoc-5/icons/9.png new file mode 100644 index 00000000..3b4991d8 Binary files /dev/null and b/web/help/taseditor/vendors/helpndoc-5/icons/9.png differ diff --git a/web/help/taseditor/vendors/html5shiv-3.7.3/html5shiv.min.js b/web/help/taseditor/vendors/html5shiv-3.7.3/html5shiv.min.js new file mode 100644 index 00000000..355afd10 --- /dev/null +++ b/web/help/taseditor/vendors/html5shiv-3.7.3/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/web/help/taseditor/vendors/imageMapResizer-1.0.10/imageMapResizer.min.js b/web/help/taseditor/vendors/imageMapResizer-1.0.10/imageMapResizer.min.js new file mode 100644 index 00000000..09ad956e --- /dev/null +++ b/web/help/taseditor/vendors/imageMapResizer-1.0.10/imageMapResizer.min.js @@ -0,0 +1,8 @@ +/*! Image Map Resizer (imageMapResizer.min.js ) - v1.0.10 - 2019-04-10 + * Desc: Resize HTML imageMap to scaled image. + * Copyright: (c) 2019 David J. Bradshaw - dave@bradshaw.net + * License: MIT + */ + +!function(){"use strict";function r(){function e(){var r={width:u.width/u.naturalWidth,height:u.height/u.naturalHeight},a={width:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-left"),10),height:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-top"),10)};i.forEach(function(e,t){var n=0;o[t].coords=e.split(",").map(function(e){var t=1==(n=1-n)?"width":"height";return a[t]+Math.floor(Number(e)*r[t])}).join(",")})}function t(e){return e.coords.replace(/ *, */g,",").replace(/ +/g,",")}function n(){clearTimeout(d),d=setTimeout(e,250)}function r(e){return document.querySelector('img[usemap="'+e+'"]')}var a=this,o=null,i=null,u=null,d=null;"function"!=typeof a._resize?(o=a.getElementsByTagName("area"),i=Array.prototype.map.call(o,t),u=r("#"+a.name)||r(a.name),a._resize=e,u.addEventListener("load",e,!1),window.addEventListener("focus",e,!1),window.addEventListener("resize",n,!1),window.addEventListener("readystatechange",e,!1),document.addEventListener("fullscreenchange",e,!1),u.width===u.naturalWidth&&u.height===u.naturalHeight||e()):a._resize()}function e(){function t(e){e&&(!function(e){if(!e.tagName)throw new TypeError("Object is not a valid DOM element");if("MAP"!==e.tagName.toUpperCase())throw new TypeError("Expected tag, found <"+e.tagName+">.")}(e),r.call(e),n.push(e))}var n;return function(e){switch(n=[],typeof e){case"undefined":case"string":Array.prototype.forEach.call(document.querySelectorAll(e||"map"),t);break;case"object":t(e);break;default:throw new TypeError("Unexpected data type ("+typeof e+").")}return n}}"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&"object"==typeof module.exports?module.exports=e():window.imageMapResize=e(),"jQuery"in window&&(window.jQuery.fn.imageMapResize=function(){return this.filter("map").each(r).end()})}(); +//# sourceMappingURL=imageMapResizer.map \ No newline at end of file diff --git a/web/help/taseditor/vendors/interactjs-1.9.22/interact.min.js b/web/help/taseditor/vendors/interactjs-1.9.22/interact.min.js new file mode 100644 index 00000000..420f876f --- /dev/null +++ b/web/help/taseditor/vendors/interactjs-1.9.22/interact.min.js @@ -0,0 +1,3 @@ +/* interact.js 1.9.22 | https://raw.github.com/taye/interact.js/master/LICENSE */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).interact=t()}}((function(){var t={};Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default=function(t){return!(!t||!t.Window)&&t instanceof t.Window};var e={};Object.defineProperty(e,"__esModule",{value:!0}),e.init=o,e.getWindow=function(e){if((0,t.default)(e))return e;return(e.ownerDocument||e).defaultView||r.window},e.window=e.realWindow=void 0;var n=void 0;e.realWindow=n;var r=void 0;function o(t){e.realWindow=n=t;var o=t.document.createTextNode("");o.ownerDocument!==t.document&&"function"==typeof t.wrap&&t.wrap(o)===o&&(t=t.wrap(t)),e.window=r=t}e.window=r,"undefined"!=typeof window&&window&&o(window);var i={};function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}Object.defineProperty(i,"__esModule",{value:!0}),i.default=void 0;var s=function(t){return!!t&&"object"===a(t)},l=function(t){return"function"==typeof t},u={window:function(n){return n===e.window||(0,t.default)(n)},docFrag:function(t){return s(t)&&11===t.nodeType},object:s,func:l,number:function(t){return"number"==typeof t},bool:function(t){return"boolean"==typeof t},string:function(t){return"string"==typeof t},element:function(t){if(!t||"object"!==a(t))return!1;var n=e.getWindow(t)||e.window;return/object|function/.test(a(n.Element))?t instanceof n.Element:1===t.nodeType&&"string"==typeof t.nodeName},plainObject:function(t){return s(t)&&!!t.constructor&&/function Object\b/.test(t.constructor.toString())},array:function(t){return s(t)&&void 0!==t.length&&l(t.splice)}};i.default=u;var c={};function f(t){var e=t.interaction;if("drag"===e.prepared.name){var n=e.prepared.axis;"x"===n?(e.coords.cur.page.y=e.coords.start.page.y,e.coords.cur.client.y=e.coords.start.client.y,e.coords.velocity.client.y=0,e.coords.velocity.page.y=0):"y"===n&&(e.coords.cur.page.x=e.coords.start.page.x,e.coords.cur.client.x=e.coords.start.client.x,e.coords.velocity.client.x=0,e.coords.velocity.page.x=0)}}function d(t){var e=t.iEvent,n=t.interaction;if("drag"===n.prepared.name){var r=n.prepared.axis;if("x"===r||"y"===r){var o="x"===r?"y":"x";e.page[o]=n.coords.start.page[o],e.client[o]=n.coords.start.client[o],e.delta[o]=0}}}Object.defineProperty(c,"__esModule",{value:!0}),c.default=void 0;var p={id:"actions/drag",install:function(t){var e=t.actions,n=t.Interactable,r=t.defaults;n.prototype.draggable=p.draggable,e.map.drag=p,e.methodDict.drag="draggable",r.actions.drag=p.defaults},listeners:{"interactions:before-action-move":f,"interactions:action-resume":f,"interactions:action-move":d,"auto-start:check":function(t){var e=t.interaction,n=t.interactable,r=t.buttons,o=n.options.drag;if(o&&o.enabled&&(!e.pointerIsDown||!/mouse|pointer/.test(e.pointerType)||0!=(r&n.options.drag.mouseButtons)))return t.action={name:"drag",axis:"start"===o.lockAxis?o.startAxis:o.lockAxis},!1}},draggable:function(t){return i.default.object(t)?(this.options.drag.enabled=!1!==t.enabled,this.setPerAction("drag",t),this.setOnEvents("drag",t),/^(xy|x|y|start)$/.test(t.lockAxis)&&(this.options.drag.lockAxis=t.lockAxis),/^(xy|x|y)$/.test(t.startAxis)&&(this.options.drag.startAxis=t.startAxis),this):i.default.bool(t)?(this.options.drag.enabled=t,this):this.options.drag},beforeMove:f,move:d,defaults:{startAxis:"xy",lockAxis:"xy"},getCursor:function(){return"move"}},v=p;c.default=v;var h={};Object.defineProperty(h,"__esModule",{value:!0}),h.default=void 0;var g={init:function(t){var e=t;g.document=e.document,g.DocumentFragment=e.DocumentFragment||y,g.SVGElement=e.SVGElement||y,g.SVGSVGElement=e.SVGSVGElement||y,g.SVGElementInstance=e.SVGElementInstance||y,g.Element=e.Element||y,g.HTMLElement=e.HTMLElement||g.Element,g.Event=e.Event,g.Touch=e.Touch||y,g.PointerEvent=e.PointerEvent||e.MSPointerEvent},document:null,DocumentFragment:null,SVGElement:null,SVGSVGElement:null,SVGElementInstance:null,Element:null,HTMLElement:null,Event:null,Touch:null,PointerEvent:null};function y(){}var m=g;h.default=m;var b={};Object.defineProperty(b,"__esModule",{value:!0}),b.default=void 0;var x={init:function(t){var n=h.default.Element,r=e.window.navigator;x.supportsTouch="ontouchstart"in t||i.default.func(t.DocumentTouch)&&h.default.document instanceof t.DocumentTouch,x.supportsPointerEvent=!1!==r.pointerEnabled&&!!h.default.PointerEvent,x.isIOS=/iP(hone|od|ad)/.test(r.platform),x.isIOS7=/iP(hone|od|ad)/.test(r.platform)&&/OS 7[^\d]/.test(r.appVersion),x.isIe9=/MSIE 9/.test(r.userAgent),x.isOperaMobile="Opera"===r.appName&&x.supportsTouch&&/Presto/.test(r.userAgent),x.prefixedMatchesSelector="matches"in n.prototype?"matches":"webkitMatchesSelector"in n.prototype?"webkitMatchesSelector":"mozMatchesSelector"in n.prototype?"mozMatchesSelector":"oMatchesSelector"in n.prototype?"oMatchesSelector":"msMatchesSelector",x.pEventTypes=x.supportsPointerEvent?h.default.PointerEvent===t.MSPointerEvent?{up:"MSPointerUp",down:"MSPointerDown",over:"mouseover",out:"mouseout",move:"MSPointerMove",cancel:"MSPointerCancel"}:{up:"pointerup",down:"pointerdown",over:"pointerover",out:"pointerout",move:"pointermove",cancel:"pointercancel"}:null,x.wheelEvent="onmousewheel"in h.default.document?"mousewheel":"wheel"},supportsTouch:null,supportsPointerEvent:null,isIOS7:null,isIOS:null,isIe9:null,isOperaMobile:null,prefixedMatchesSelector:null,pEventTypes:null,wheelEvent:null};var w=x;b.default=w;var _={};function S(t){var e=t.parentNode;if(i.default.docFrag(e)){for(;(e=e.host)&&i.default.docFrag(e););return e}return e}function P(t,n){return e.window!==e.realWindow&&(n=n.replace(/\/deep\//g," ")),t[b.default.prefixedMatchesSelector](n)}Object.defineProperty(_,"__esModule",{value:!0}),_.nodeContains=function(t,e){if(t.contains)return t.contains(e);for(;e;){if(e===t)return!0;e=e.parentNode}return!1},_.closest=function(t,e){for(;i.default.element(t);){if(P(t,e))return t;t=S(t)}return null},_.parentNode=S,_.matchesSelector=P,_.indexOfDeepestElement=function(t){for(var n,r=[],o=0;o=m&&(n=o);else n=o}else n=o}var v,g,y,m;return n},_.matchesUpTo=function(t,e,n){for(;i.default.element(t);){if(P(t,e))return!0;if((t=S(t))===n)return P(t,e)}return!1},_.getActualElement=function(t){return t.correspondingUseElement||t},_.getScrollXY=T,_.getElementClientRect=M,_.getElementRect=function(t){var n=M(t);if(!b.default.isIOS7&&n){var r=T(e.getWindow(t));n.left+=r.x,n.right+=r.x,n.top+=r.y,n.bottom+=r.y}return n},_.getPath=function(t){var e=[];for(;t;)e.push(t),t=S(t);return e},_.trySelector=function(t){if(!i.default.string(t))return!1;return h.default.document.querySelector(t),!0};var O=function(t){return t.parentNode||t.host};function E(t,e){for(var n,r=[],o=t;(n=O(o))&&o!==e&&n!==o.ownerDocument;)r.unshift(o),o=n;return r}function T(t){return{x:(t=t||e.window).scrollX||t.document.documentElement.scrollLeft,y:t.scrollY||t.document.documentElement.scrollTop}}function M(t){var e=t instanceof h.default.SVGElement?t.getBoundingClientRect():t.getClientRects()[0];return e&&{left:e.left,right:e.right,top:e.top,bottom:e.bottom,width:e.width||e.right-e.left,height:e.height||e.bottom-e.top}}var j={};Object.defineProperty(j,"__esModule",{value:!0}),j.default=function(t,e){for(var n in e)t[n]=e[n];return t};var k={};function I(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n1?q(e):e[0];U(r,t.page),N(r,t.client),t.timeStamp=n},W.getTouchPair=V,W.pointerAverage=q,W.touchBBox=function(t){if(!t.length)return null;var e=V(t),n=Math.min(e[0].pageX,e[1].pageX),r=Math.min(e[0].pageY,e[1].pageY),o=Math.max(e[0].pageX,e[1].pageX),i=Math.max(e[0].pageY,e[1].pageY);return{x:n,y:r,left:n,top:r,right:o,bottom:i,width:o-n,height:i-r}},W.touchDistance=function(t,e){var n=e+"X",r=e+"Y",o=V(t),i=o[0][n]-o[1][n],a=o[0][r]-o[1][r];return(0,R.default)(i,a)},W.touchAngle=function(t,e){var n=e+"X",r=e+"Y",o=V(t),i=o[1][n]-o[0][n],a=o[1][r]-o[0][r];return 180*Math.atan2(a,i)/Math.PI},W.getPointerType=function(t){return i.default.string(t.pointerType)?t.pointerType:i.default.number(t.pointerType)?[void 0,void 0,"touch","pen","mouse"][t.pointerType]:/touch/.test(t.type)||t instanceof h.default.Touch?"touch":"mouse"},W.getEventTargets=function(t){var e=i.default.func(t.composedPath)?t.composedPath():t.path;return[_.getActualElement(e?e[0]:t.target),_.getActualElement(t.currentTarget)]},W.newCoords=function(){return{page:{x:0,y:0},client:{x:0,y:0},timeStamp:0}},W.coordsToEvent=function(t){return{coords:t,get page(){return this.coords.page},get client(){return this.coords.client},get timeStamp(){return this.coords.timeStamp},get pageX(){return this.coords.page.x},get pageY(){return this.coords.page.y},get clientX(){return this.coords.client.x},get clientY(){return this.coords.client.y},get pointerId(){return this.coords.pointerId},get target(){return this.coords.target},get type(){return this.coords.type},get pointerType(){return this.coords.pointerType},get buttons(){return this.coords.buttons},preventDefault:function(){}}},Object.defineProperty(W,"pointerExtend",{enumerable:!0,get:function(){return F.default}});var $={};function G(t,e){for(var n=0;ns.left&&f.xs.top&&f.y=s.left&&h<=s.right&&g>=s.top&&g<=s.bottom}if(v&&i.default.number(u)){var y=Math.max(0,Math.min(s.right,v.right)-Math.max(s.left,v.left))*Math.max(0,Math.min(s.bottom,v.bottom)-Math.max(s.top,v.top))/(v.width*v.height);l=y>=u}t.options.drop.checker&&(l=t.options.drop.checker(e,n,l,t,a,r,o));return l}(this,t,e,n,r,o,a)},n.dynamicDrop=function(e){return i.default.bool(e)?(t.dynamicDrop=e,n):t.dynamicDrop},(0,j.default)(e.phaselessTypes,{dragenter:!0,dragleave:!0,dropactivate:!0,dropdeactivate:!0,dropmove:!0,drop:!0}),e.methodDict.drop="dropzone",t.dynamicDrop=!1,o.actions.drop=vt.defaults},listeners:{"interactions:before-action-start":function(t){var e=t.interaction;"drag"===e.prepared.name&&(e.dropState={cur:{dropzone:null,element:null},prev:{dropzone:null,element:null},rejected:null,events:null,activeDrops:[]})},"interactions:after-action-start":function(t,e){var n=t.interaction,r=(t.event,t.iEvent);if("drag"===n.prepared.name){var o=n.dropState;o.activeDrops=null,o.events=null,o.activeDrops=ut(e,n.element),o.events=ft(n,0,r),o.events.activate&&(lt(o.activeDrops,o.events.activate),e.fire("actions/drop:start",{interaction:n,dragEvent:r}))}},"interactions:action-move":pt,"interactions:after-action-move":function(t,e){var n=t.interaction,r=t.iEvent;"drag"===n.prepared.name&&(dt(n,n.dropState.events),e.fire("actions/drop:move",{interaction:n,dragEvent:r}),n.dropState.events={})},"interactions:action-end":function(t,e){if("drag"===t.interaction.prepared.name){var n=t.interaction,r=t.iEvent;pt(t,e),dt(n,n.dropState.events),e.fire("actions/drop:end",{interaction:n,dragEvent:r})}},"interactions:stop":function(t){var e=t.interaction;if("drag"===e.prepared.name){var n=e.dropState;n&&(n.activeDrops=null,n.events=null,n.cur.dropzone=null,n.cur.element=null,n.prev.dropzone=null,n.prev.element=null,n.rejected=!1)}}},getActiveDrops:ut,getDrop:ct,getDropEvents:ft,fireDropEvents:dt,defaults:{enabled:!1,accept:null,overlap:"pointer"}},ht=vt;st.default=ht;var gt={};function yt(t){var e=t.interaction,n=t.iEvent,r=t.phase;if("gesture"===e.prepared.name){var o=e.pointers.map((function(t){return t.pointer})),a="start"===r,s="end"===r,l=e.interactable.options.deltaSource;if(n.touches=[o[0],o[1]],a)n.distance=W.touchDistance(o,l),n.box=W.touchBBox(o),n.scale=1,n.ds=0,n.angle=W.touchAngle(o,l),n.da=0,e.gesture.startDistance=n.distance,e.gesture.startAngle=n.angle;else if(s){var u=e.prevEvent;n.distance=u.distance,n.box=u.box,n.scale=u.scale,n.ds=0,n.angle=u.angle,n.da=0}else n.distance=W.touchDistance(o,l),n.box=W.touchBBox(o),n.scale=n.distance/e.gesture.startDistance,n.angle=W.touchAngle(o,l),n.ds=n.scale-e.gesture.scale,n.da=n.angle-e.gesture.angle;e.gesture.distance=n.distance,e.gesture.angle=n.angle,i.default.number(n.scale)&&n.scale!==1/0&&!isNaN(n.scale)&&(e.gesture.scale=n.scale)}}Object.defineProperty(gt,"__esModule",{value:!0}),gt.default=void 0;var mt={id:"actions/gesture",before:["actions/drag","actions/resize"],install:function(t){var e=t.actions,n=t.Interactable,r=t.defaults;n.prototype.gesturable=function(t){return i.default.object(t)?(this.options.gesture.enabled=!1!==t.enabled,this.setPerAction("gesture",t),this.setOnEvents("gesture",t),this):i.default.bool(t)?(this.options.gesture.enabled=t,this):this.options.gesture},e.map.gesture=mt,e.methodDict.gesture="gesturable",r.actions.gesture=mt.defaults},listeners:{"interactions:action-start":yt,"interactions:action-move":yt,"interactions:action-end":yt,"interactions:new":function(t){t.interaction.gesture={angle:0,distance:0,scale:1,startAngle:0,startDistance:0}},"auto-start:check":function(t){if(!(t.interaction.pointers.length<2)){var e=t.interactable.options.gesture;if(e&&e.enabled)return t.action={name:"gesture"},!1}}},defaults:{},getCursor:function(){return""}},bt=mt;gt.default=bt;var xt={};function wt(t,e,n,r,o,a,s){if(!e)return!1;if(!0===e){var l=i.default.number(a.width)?a.width:a.right-a.left,u=i.default.number(a.height)?a.height:a.bottom-a.top;if(s=Math.min(s,Math.abs(("left"===t||"right"===t?l:u)/2)),l<0&&("left"===t?t="right":"right"===t&&(t="left")),u<0&&("top"===t?t="bottom":"bottom"===t&&(t="top")),"left"===t)return n.x<(l>=0?a.left:a.right)+s;if("top"===t)return n.y<(u>=0?a.top:a.bottom)+s;if("right"===t)return n.x>(l>=0?a.right:a.left)-s;if("bottom"===t)return n.y>(u>=0?a.bottom:a.top)-s}return!!i.default.element(r)&&(i.default.element(e)?e===r:_.matchesUpTo(r,e,o))}function _t(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.resizeAxes){var r=e;n.interactable.options.resize.square?("y"===n.resizeAxes?r.delta.x=r.delta.y:r.delta.y=r.delta.x,r.axes="xy"):(r.axes=n.resizeAxes,"x"===n.resizeAxes?r.delta.y=0:"y"===n.resizeAxes&&(r.delta.x=0))}}Object.defineProperty(xt,"__esModule",{value:!0}),xt.default=void 0;var St={id:"actions/resize",before:["actions/drag"],install:function(t){var e=t.actions,n=t.browser,r=t.Interactable,o=t.defaults;St.cursors=function(t){return t.isIe9?{x:"e-resize",y:"s-resize",xy:"se-resize",top:"n-resize",left:"w-resize",bottom:"s-resize",right:"e-resize",topleft:"se-resize",bottomright:"se-resize",topright:"ne-resize",bottomleft:"ne-resize"}:{x:"ew-resize",y:"ns-resize",xy:"nwse-resize",top:"ns-resize",left:"ew-resize",bottom:"ns-resize",right:"ew-resize",topleft:"nwse-resize",bottomright:"nwse-resize",topright:"nesw-resize",bottomleft:"nesw-resize"}}(n),St.defaultMargin=n.supportsTouch||n.supportsPointerEvent?20:10,r.prototype.resizable=function(e){return function(t,e,n){if(i.default.object(e))return t.options.resize.enabled=!1!==e.enabled,t.setPerAction("resize",e),t.setOnEvents("resize",e),i.default.string(e.axis)&&/^x$|^y$|^xy$/.test(e.axis)?t.options.resize.axis=e.axis:null===e.axis&&(t.options.resize.axis=n.defaults.actions.resize.axis),i.default.bool(e.preserveAspectRatio)?t.options.resize.preserveAspectRatio=e.preserveAspectRatio:i.default.bool(e.square)&&(t.options.resize.square=e.square),t;if(i.default.bool(e))return t.options.resize.enabled=e,t;return t.options.resize}(this,e,t)},e.map.resize=St,e.methodDict.resize="resizable",o.actions.resize=St.defaults},listeners:{"interactions:new":function(t){t.interaction.resizeAxes="xy"},"interactions:action-start":function(t){!function(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.prepared.edges){var r=e,o=n.rect;n._rects={start:(0,j.default)({},o),corrected:(0,j.default)({},o),previous:(0,j.default)({},o),delta:{left:0,right:0,width:0,top:0,bottom:0,height:0}},r.edges=n.prepared.edges,r.rect=n._rects.corrected,r.deltaRect=n._rects.delta}}(t),_t(t)},"interactions:action-move":function(t){!function(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.prepared.edges){var r=e,o=n.interactable.options.resize.invert,i="reposition"===o||"negate"===o,a=n.rect,s=n._rects,l=s.start,u=s.corrected,c=s.delta,f=s.previous;if((0,j.default)(f,u),i){if((0,j.default)(u,a),"reposition"===o){if(u.top>u.bottom){var d=u.top;u.top=u.bottom,u.bottom=d}if(u.left>u.right){var p=u.left;u.left=u.right,u.right=p}}}else u.top=Math.min(a.top,l.bottom),u.bottom=Math.max(a.bottom,l.top),u.left=Math.min(a.left,l.right),u.right=Math.max(a.right,l.left);for(var v in u.width=u.right-u.left,u.height=u.bottom-u.top,u)c[v]=u[v]-f[v];r.edges=n.prepared.edges,r.rect=u,r.deltaRect=c}}(t),_t(t)},"interactions:action-end":function(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.prepared.edges){var r=e;r.edges=n.prepared.edges,r.rect=n._rects.corrected,r.deltaRect=n._rects.delta}},"auto-start:check":function(t){var e=t.interaction,n=t.interactable,r=t.element,o=t.rect,a=t.buttons;if(o){var s=(0,j.default)({},e.coords.cur.page),l=n.options.resize;if(l&&l.enabled&&(!e.pointerIsDown||!/mouse|pointer/.test(e.pointerType)||0!=(a&l.mouseButtons))){if(i.default.object(l.edges)){var u={left:!1,right:!1,top:!1,bottom:!1};for(var c in u)u[c]=wt(c,l.edges[c],s,e._latestPointer.eventTarget,r,o,l.margin||St.defaultMargin);u.left=u.left&&!u.right,u.top=u.top&&!u.bottom,(u.left||u.right||u.top||u.bottom)&&(t.action={name:"resize",edges:u})}else{var f="y"!==l.axis&&s.x>o.right-St.defaultMargin,d="x"!==l.axis&&s.y>o.bottom-St.defaultMargin;(f||d)&&(t.action={name:"resize",axes:(f?"x":"")+(d?"y":"")})}return!t.action&&void 0}}}},defaults:{square:!1,preserveAspectRatio:!1,axis:"xy",margin:NaN,edges:null,invert:"none"},cursors:null,getCursor:function(t){var e=t.edges,n=t.axis,r=t.name,o=St.cursors,i=null;if(n)i=o[r+n];else if(e){for(var a="",s=["top","bottom","left","right"],l=0;l=1){var c={x:zt.x*u,y:zt.y*u};if(c.x||c.y){var f=Rt(a);i.default.window(a)?a.scrollBy(c.x,c.y):a&&(a.scrollLeft+=c.x,a.scrollTop+=c.y);var d=Rt(a),p={x:d.x-f.x,y:d.y-f.y};(p.x||p.y)&&e.fire({type:"autoscroll",target:n,interactable:e,delta:p,interaction:t,container:a})}zt.prevTime=s}zt.isScrolling&&(Mt.default.cancel(zt.i),zt.i=Mt.default.request(zt.scroll))},check:function(t,e){var n=t.options;return n[e].autoScroll&&n[e].autoScroll.enabled},onInteractionMove:function(t){var e=t.interaction,n=t.pointer;if(e.interacting()&&zt.check(e.interactable,e.prepared.name))if(e.simulation)zt.x=zt.y=0;else{var r,o,a,s,l=e.interactable,u=e.element,c=e.prepared.name,f=l.options[c].autoScroll,d=Ct(f.container,l,u);if(i.default.window(d))s=n.clientXd.innerWidth-zt.margin,a=n.clientY>d.innerHeight-zt.margin;else{var p=_.getElementClientRect(d);s=n.clientXp.right-zt.margin,a=n.clientY>p.bottom-zt.margin}zt.x=o?1:s?-1:0,zt.y=a?1:r?-1:0,zt.isScrolling||(zt.margin=f.margin,zt.speed=f.speed,zt.start(e))}}};function Ct(t,n,r){return(i.default.string(t)?(0,k.getStringOptionResult)(t,n,r):t)||(0,e.getWindow)(r)}function Rt(t){return i.default.window(t)&&(t=window.document.body),{x:t.scrollLeft,y:t.scrollTop}}var Ft={id:"auto-scroll",install:function(t){var e=t.defaults,n=t.actions;t.autoScroll=zt,zt.now=function(){return t.now()},n.phaselessTypes.autoscroll=!0,e.perAction.autoScroll=zt.defaults},listeners:{"interactions:new":function(t){t.interaction.autoScroll=null},"interactions:destroy":function(t){t.interaction.autoScroll=null,zt.stop(),zt.interaction&&(zt.interaction=null)},"interactions:stop":zt.stop,"interactions:action-move":function(t){return zt.onInteractionMove(t)}}};At.default=Ft;var Xt={};Object.defineProperty(Xt,"__esModule",{value:!0}),Xt.warnOnce=function(t,n){var r=!1;return function(){return r||(e.window.console.warn(n),r=!0),t.apply(this,arguments)}},Xt.copyAction=function(t,e){return t.name=e.name,t.axis=e.axis,t.edges=e.edges,t};var Yt={};function Wt(t){return i.default.bool(t)?(this.options.styleCursor=t,this):null===t?(delete this.options.styleCursor,this):this.options.styleCursor}function Lt(t){return i.default.func(t)?(this.options.actionChecker=t,this):null===t?(delete this.options.actionChecker,this):this.options.actionChecker}Object.defineProperty(Yt,"__esModule",{value:!0}),Yt.default=void 0;var Bt={id:"auto-start/interactableMethods",install:function(t){var e=t.Interactable;e.prototype.getAction=function(e,n,r,o){var i=function(t,e,n,r,o){var i=t.getRect(r),a=e.buttons||{0:1,1:4,3:8,4:16}[e.button],s={action:null,interactable:t,interaction:n,element:r,rect:i,buttons:a};return o.fire("auto-start:check",s),s.action}(this,n,r,o,t);return this.options.actionChecker?this.options.actionChecker(e,n,i,this,o,r):i},e.prototype.ignoreFrom=(0,Xt.warnOnce)((function(t){return this._backCompatOption("ignoreFrom",t)}),"Interactable.ignoreFrom() has been deprecated. Use Interactble.draggable({ignoreFrom: newValue})."),e.prototype.allowFrom=(0,Xt.warnOnce)((function(t){return this._backCompatOption("allowFrom",t)}),"Interactable.allowFrom() has been deprecated. Use Interactble.draggable({allowFrom: newValue})."),e.prototype.actionChecker=Lt,e.prototype.styleCursor=Wt}};Yt.default=Bt;var Ut={};function Nt(t,e,n,r,o){return e.testIgnoreAllow(e.options[t.name],n,r)&&e.options[t.name].enabled&&Gt(e,n,t,o)?t:null}function Vt(t,e,n,r,o,i,a){for(var s=0,l=r.length;s=s)return!1;if(d.interactable===t){if((u+=p===n.name?1:0)>=i)return!1;if(d.element===e&&(c++,p===n.name&&c>=a))return!1}}}return s>0}function Ht(t,e){return i.default.number(t)?(e.autoStart.maxInteractions=t,this):e.autoStart.maxInteractions}function Kt(t,e,n){var r=n.autoStart.cursorElement;r&&r!==t&&(r.style.cursor=""),t.ownerDocument.documentElement.style.cursor=e,t.style.cursor=e,n.autoStart.cursorElement=e?t:null}function Zt(t,e){var n=t.interactable,r=t.element,o=t.prepared;if("mouse"===t.pointerType&&n&&n.options.styleCursor){var a="";if(o.name){var s=n.options[o.name].cursorChecker;a=i.default.func(s)?s(o,n,r,t._interacting):e.actions.map[o.name].getCursor(o)}Kt(t.element,a||"",e)}else e.autoStart.cursorElement&&Kt(e.autoStart.cursorElement,"",e)}Object.defineProperty(Ut,"__esModule",{value:!0}),Ut.default=void 0;var Jt={id:"auto-start/base",before:["actions"],install:function(t){var e=t.interactStatic,n=t.defaults;t.usePlugin(Yt.default),n.base.actionChecker=null,n.base.styleCursor=!0,(0,j.default)(n.perAction,{manualStart:!1,max:1/0,maxPerElement:1,allowFrom:null,ignoreFrom:null,mouseButtons:1}),e.maxInteractions=function(e){return Ht(e,t)},t.autoStart={maxInteractions:1/0,withinInteractionLimit:Gt,cursorElement:null}},listeners:{"interactions:down":function(t,e){var n=t.interaction,r=t.pointer,o=t.event,i=t.eventTarget;n.interacting()||$t(n,qt(n,r,o,i,e),e)},"interactions:move":function(t,e){!function(t,e){var n=t.interaction,r=t.pointer,o=t.event,i=t.eventTarget;"mouse"!==n.pointerType||n.pointerIsDown||n.interacting()||$t(n,qt(n,r,o,i,e),e)}(t,e),function(t,e){var n=t.interaction;if(n.pointerIsDown&&!n.interacting()&&n.pointerWasMoved&&n.prepared.name){e.fire("autoStart:before-start",t);var r=n.interactable,o=n.prepared.name;o&&r&&(r.options[o].manualStart||!Gt(r,n.element,n.prepared,e)?n.stop():(n.start(n.prepared,r,n.element),Zt(n,e)))}}(t,e)},"interactions:stop":function(t,e){var n=t.interaction,r=n.interactable;r&&r.options.styleCursor&&Kt(n.element,"",e)}},maxInteractions:Ht,withinInteractionLimit:Gt,validateAction:Nt};Ut.default=Jt;var Qt={};Object.defineProperty(Qt,"__esModule",{value:!0}),Qt.default=void 0;var te={id:"auto-start/dragAxis",listeners:{"autoStart:before-start":function(t,e){var n=t.interaction,r=t.eventTarget,o=t.dx,a=t.dy;if("drag"===n.prepared.name){var s=Math.abs(o),l=Math.abs(a),u=n.interactable.options.drag,c=u.startAxis,f=s>l?"x":s0&&(e.autoStartHoldTimer=setTimeout((function(){e.start(e.prepared,e.interactable,e.element)}),n))},"interactions:move":function(t){var e=t.interaction,n=t.duplicate;e.autoStartHoldTimer&&e.pointerWasMoved&&!n&&(clearTimeout(e.autoStartHoldTimer),e.autoStartHoldTimer=null)},"autoStart:before-start":function(t){var e=t.interaction;ne(e)>0&&(e.prepared.name=null)}},getHoldDuration:ne};ee.default=re;var oe={};Object.defineProperty(oe,"__esModule",{value:!0}),oe.default=void 0;var ie={id:"auto-start",install:function(t){t.usePlugin(Ut.default),t.usePlugin(ee.default),t.usePlugin(Qt.default)}};oe.default=ie;var ae={};Object.defineProperty(ae,"__esModule",{value:!0}),ae.default=void 0;ae.default={};var se={};function le(t){return/^(always|never|auto)$/.test(t)?(this.options.preventDefault=t,this):i.default.bool(t)?(this.options.preventDefault=t?"always":"never",this):this.options.preventDefault}function ue(t){var e=t.interaction,n=t.event;e.interactable&&e.interactable.checkAndPreventDefault(n)}function ce(t){var n=t.Interactable;n.prototype.preventDefault=le,n.prototype.checkAndPreventDefault=function(n){return function(t,n,r){var o=t.options.preventDefault;if("never"!==o)if("always"!==o){if(n.events.supportsPassive&&/^touch(start|move)$/.test(r.type)){var a=(0,e.getWindow)(r.target).document,s=n.getDocOptions(a);if(!s||!s.events||!1!==s.events.passive)return}/^(mouse|pointer|touch)*(down|start)/i.test(r.type)||i.default.element(r.target)&&(0,_.matchesSelector)(r.target,"input,select,textarea,[contenteditable=true],[contenteditable=true] *")||r.preventDefault()}else r.preventDefault()}(this,t,n)},t.interactions.docEvents.push({type:"dragstart",listener:function(e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);n1&&void 0!==arguments[1]?arguments[1]:{},n=e.logger,r=t.Interactable,o=t.defaults;t.logger=n||console,o.base.devTools={ignore:{}},r.prototype.devTools=function(t){return t?((0,j.default)(this.options.devTools,t),this):this.options.devTools}},listeners:{"interactions:action-start":function(t,e){for(var n=t.interaction,r=0;rt.length)&&(e=t.length);for(var n=0,r=Array(e);n150)return null;var e=180*Math.atan2(t.prevEvent.velocityY,t.prevEvent.velocityX)/Math.PI;e<0&&(e+=360);var n=112.5<=e&&e<247.5,r=202.5<=e&&e<337.5;return{up:r,down:!r&&22.5<=e&&e<157.5,left:n,right:!n&&(292.5<=e||e<67.5),angle:e,speed:t.prevEvent.speed,velocity:{x:t.prevEvent.velocityX,y:t.prevEvent.velocityY}}}},{key:"preventDefault",value:function(){}},{key:"stopImmediatePropagation",value:function(){this.immediatePropagationStopped=this.propagationStopped=!0}},{key:"stopPropagation",value:function(){this.propagationStopped=!0}}])&&Re(e.prototype,n),r&&Re(e,r),i}($.BaseEvent);ze.InteractEvent=Be,Object.defineProperties(Be.prototype,{pageX:{get:function(){return this.page.x},set:function(t){this.page.x=t}},pageY:{get:function(){return this.page.y},set:function(t){this.page.y=t}},clientX:{get:function(){return this.client.x},set:function(t){this.client.x=t}},clientY:{get:function(){return this.client.y},set:function(t){this.client.y=t}},dx:{get:function(){return this.delta.x},set:function(t){this.delta.x=t}},dy:{get:function(){return this.delta.y},set:function(t){this.delta.y=t}},velocityX:{get:function(){return this.velocity.x},set:function(t){this.velocity.x=t}},velocityY:{get:function(){return this.velocity.y},set:function(t){this.velocity.y=t}}});var Ue={};Object.defineProperty(Ue,"__esModule",{value:!0}),Ue.PointerInfo=void 0;Ue.PointerInfo=function t(e,n,r,o,i){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.id=void 0,this.pointer=void 0,this.event=void 0,this.downTime=void 0,this.downTarget=void 0,this.id=e,this.pointer=n,this.event=r,this.downTime=o,this.downTarget=i};var Ne,Ve,qe={};function $e(t,e){for(var n=0;nthis.pointerMoveTolerance);var a=this.getPointerIndex(t),s={pointer:t,pointerIndex:a,pointerInfo:this.pointers[a],event:e,type:"move",eventTarget:n,dx:r,dy:o,duplicate:i,interaction:this};i||W.setCoordVelocity(this.coords.velocity,this.coords.delta),this._scopeFire("interactions:move",s),i||this.simulation||(this.interacting()&&(s.type=null,this.move(s)),this.pointerWasMoved&&W.copyCoords(this.coords.prev,this.coords.cur))}},{key:"move",value:function(t){t&&t.event||W.setZeroCoords(this.coords.delta),(t=(0,j.default)({pointer:this._latestPointer.pointer,event:this._latestPointer.event,eventTarget:this._latestPointer.eventTarget,interaction:this},t||{})).phase="move",this._doPhase(t)}},{key:"pointerUp",value:function(t,e,n,r){var o=this.getPointerIndex(t);-1===o&&(o=this.updatePointer(t,e,n,!1));var i=/cancel$/i.test(e.type)?"cancel":"up";this._scopeFire("interactions:".concat(i),{pointer:t,pointerIndex:o,pointerInfo:this.pointers[o],event:e,eventTarget:n,type:i,curEventTarget:r,interaction:this}),this.simulation||this.end(e),this.removePointer(t,e)}},{key:"documentBlur",value:function(t){this.end(t),this._scopeFire("interactions:blur",{event:t,type:"blur",interaction:this})}},{key:"end",value:function(t){var e;this._ending=!0,t=t||this._latestPointer.event,this.interacting()&&(e=this._doPhase({event:t,interaction:this,phase:"end"})),this._ending=!1,!0===e&&this.stop()}},{key:"currentAction",value:function(){return this._interacting?this.prepared.name:null}},{key:"interacting",value:function(){return this._interacting}},{key:"stop",value:function(){this._scopeFire("interactions:stop",{interaction:this}),this.interactable=this.element=null,this._interacting=!1,this._stopped=!0,this.prepared.name=this.prevEvent=null}},{key:"getPointerIndex",value:function(t){var e=W.getPointerId(t);return"mouse"===this.pointerType||"pen"===this.pointerType?this.pointers.length-1:K.findIndex(this.pointers,(function(t){return t.id===e}))}},{key:"getPointerInfo",value:function(t){return this.pointers[this.getPointerIndex(t)]}},{key:"updatePointer",value:function(t,e,n,r){var o=W.getPointerId(t),i=this.getPointerIndex(t),a=this.pointers[i];return r=!1!==r&&(r||/(down|start)$/i.test(e.type)),a?a.pointer=t:(a=new Ue.PointerInfo(o,t,e,null,null),i=this.pointers.length,this.pointers.push(a)),W.setCoords(this.coords.cur,this.pointers.map((function(t){return t.pointer})),this._now()),W.setCoordDeltas(this.coords.delta,this.coords.prev,this.coords.cur),r&&(this.pointerIsDown=!0,a.downTime=this.coords.cur.timeStamp,a.downTarget=n,W.pointerExtend(this.downPointer,t),this.interacting()||(W.copyCoords(this.coords.start,this.coords.cur),W.copyCoords(this.coords.prev,this.coords.cur),this.downEvent=e,this.pointerWasMoved=!1)),this._updateLatestPointer(t,e,n),this._scopeFire("interactions:update-pointer",{pointer:t,event:e,eventTarget:n,down:r,pointerInfo:a,pointerIndex:i,interaction:this}),i}},{key:"removePointer",value:function(t,e){var n=this.getPointerIndex(t);if(-1!==n){var r=this.pointers[n];this._scopeFire("interactions:remove-pointer",{pointer:t,event:e,eventTarget:null,pointerIndex:n,pointerInfo:r,interaction:this}),this.pointers.splice(n,1),this.pointerIsDown=!1}}},{key:"_updateLatestPointer",value:function(t,e,n){this._latestPointer.pointer=t,this._latestPointer.event=e,this._latestPointer.eventTarget=n}},{key:"destroy",value:function(){this._latestPointer.pointer=null,this._latestPointer.event=null,this._latestPointer.eventTarget=null}},{key:"_createPreparedEvent",value:function(t,e,n,r){return new ze.InteractEvent(this,t,this.prepared.name,e,this.element,n,r)}},{key:"_fireEvent",value:function(t){this.interactable.fire(t),(!this.prevEvent||t.timeStamp>=this.prevEvent.timeStamp)&&(this.prevEvent=t)}},{key:"_doPhase",value:function(t){var e=t.event,n=t.phase,r=t.preEnd,o=t.type,i=this.rect;if(i&&"move"===n&&(k.addEdges(this.edges,i,this.coords.delta[this.interactable.options.deltaSource]),i.width=i.right-i.left,i.height=i.bottom-i.top),!1===this._scopeFire("interactions:before-action-".concat(n),t))return!1;var a=t.iEvent=this._createPreparedEvent(e,n,r,o);return this._scopeFire("interactions:action-".concat(n),t),"start"===n&&(this.prevEvent=a),this._fireEvent(a),this._scopeFire("interactions:after-action-".concat(n),t),!0}},{key:"_now",value:function(){return Date.now()}}]),t}();qe.Interaction=Ke;var Ze=Ke;qe.default=Ze;var Je={};function Qe(t){t.pointerIsDown&&(rn(t.coords.cur,t.offset.total),t.offset.pending.x=0,t.offset.pending.y=0)}function tn(t){en(t.interaction)}function en(t){if(!function(t){return!(!t.offset.pending.x&&!t.offset.pending.y)}(t))return!1;var e=t.offset.pending;return rn(t.coords.cur,e),rn(t.coords.delta,e),k.addEdges(t.edges,t.rect,e),e.x=0,e.y=0,!0}function nn(t){var e=t.x,n=t.y;this.offset.pending.x+=e,this.offset.pending.y+=n,this.offset.total.x+=e,this.offset.total.y+=n}function rn(t,e){var n=t.page,r=t.client,o=e.x,i=e.y;n.x+=o,n.y+=i,r.x+=o,r.y+=i}Object.defineProperty(Je,"__esModule",{value:!0}),Je.addTotal=Qe,Je.applyPending=en,Je.default=void 0,qe._ProxyMethods.offsetBy="";var on={id:"offset",before:["modifiers","pointer-events","actions","inertia"],install:function(t){t.Interaction.prototype.offsetBy=nn},listeners:{"interactions:new":function(t){t.interaction.offset={total:{x:0,y:0},pending:{x:0,y:0}}},"interactions:update-pointer":function(t){return Qe(t.interaction)},"interactions:before-action-start":tn,"interactions:before-action-move":tn,"interactions:before-action-end":function(t){var e=t.interaction;if(en(e))return e.move({offset:!0}),e.end(),!1},"interactions:stop":function(t){var e=t.interaction;e.offset.total.x=0,e.offset.total.y=0,e.offset.pending.x=0,e.offset.pending.y=0}}};Je.default=on;var an={};function sn(t,e){for(var n=0;nn.minSpeed&&o>n.endSpeed)this.startInertia();else{if(i.result=i.setAll(this.modifierArg),!i.result.changed)return!1;this.startSmoothEnd()}return e.modification.result.rect=null,e.offsetBy(this.targetOffset),e._doPhase({interaction:e,event:t,phase:"inertiastart"}),e.offsetBy({x:-this.targetOffset.x,y:-this.targetOffset.y}),e.modification.result.rect=null,this.active=!0,e.simulation=this,!0}},{key:"startInertia",value:function(){var t=this,e=this.interaction.coords.velocity.client,n=un(this.interaction),r=n.resistance,o=-Math.log(n.endSpeed/this.v0)/r;this.targetOffset={x:(e.x-o)/r,y:(e.y-o)/r},this.te=o,this.lambda_v0=r/this.v0,this.one_ve_v0=1-n.endSpeed/this.v0;var i=this.modification,a=this.modifierArg;a.pageCoords={x:this.startCoords.x+this.targetOffset.x,y:this.startCoords.y+this.targetOffset.y},i.result=i.setAll(a),i.result.changed&&(this.isModified=!0,this.modifiedOffset={x:this.targetOffset.x+i.result.delta.x,y:this.targetOffset.y+i.result.delta.y}),this.onNextFrame((function(){return t.inertiaTick()}))}},{key:"startSmoothEnd",value:function(){var t=this;this.smoothEnd=!0,this.isModified=!0,this.targetOffset={x:this.modification.result.delta.x,y:this.modification.result.delta.y},this.onNextFrame((function(){return t.smoothEndTick()}))}},{key:"onNextFrame",value:function(t){var e=this;this.timeout=Mt.default.request((function(){e.active&&t()}))}},{key:"inertiaTick",value:function(){var t,e,n,r,o,i,a,s=this,l=this.interaction,u=un(l).resistance,c=(l._now()-this.t0)/1e3;if(c=0;n--){var r=e[n],o=r.selector,a=r.context,s=r.listeners;o===this.target&&a===this._context&&e.splice(n,1);for(var l=s.length-1;l>=0;l--)this._scopeEvents.removeDelegate(this.target,this._context,t,s[l][0],s[l][1])}else this._scopeEvents.remove(this.target,"all")}}]),t}();mn.Interactable=wn;var _n={};function Sn(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);n=0;a--){var p=f[a];if(p.selector===t&&p.context===e){for(var v=p.listeners,h=v.length-1;h>=0;h--){var g=Tn(v[h],2),y=g[0],m=g[1],b=m.capture,x=m.passive;if(y===o&&b===c.capture&&x===c.passive){v.splice(h,1),v.length||(f.splice(a,1),s(e,r,l),s(e,r,u,!0)),d=!0;break}}if(d)break}}},delegateListener:l,delegateUseCapture:u,delegatedEvents:n,documents:r,targets:e,supportsOptions:!1,supportsPassive:!1};function a(t,n,r,i){var a=kn(i),s=K.find(e,(function(e){return e.eventTarget===t}));s||(s={eventTarget:t,events:{}},e.push(s)),s.events[n]||(s.events[n]=[]),t.addEventListener&&!K.contains(s.events[n],r)&&(t.addEventListener(n,r,o.supportsOptions?a:a.capture),s.events[n].push(r))}function s(t,n,r,i){var a=kn(i),l=K.findIndex(e,(function(e){return e.eventTarget===t})),u=e[l];if(u&&u.events)if("all"!==n){var c=!1,f=u.events[n];if(f){if("all"===r){for(var d=f.length-1;d>=0;d--)s(t,n,f[d],a);return}for(var p=0;p=2)continue;if(!o.interacting()&&e===o.pointerType)return o}return null}};function Cn(t,e){return t.pointers.some((function(t){return t.id===e}))}var Rn=zn;An.default=Rn;var Fn={};function Xn(t){return(Xn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function Yn(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(t)))return;var n=[],r=!0,o=!1,i=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){o=!0,i=t}finally{try{r||null==s.return||s.return()}finally{if(o)throw i}}return n}(t,e)||function(t,e){if(!t)return;if("string"==typeof t)return Wn(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Wn(t,e)}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Wn(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n=0;r--){var o=e.interactions.list[r];o.interactable===n&&(o.stop(),e.fire("interactions:destroy",{interaction:o}),o.destroy(),e.interactions.list.length>2&&e.interactions.list.splice(r,1))}}},onDocSignal:Kn,doOnInteractions:Gn,methodNames:$n};Fn.default=Zn;var Jn={};function Qn(t){return(Qn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function tr(t,e,n){return(tr="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var r=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=or(t)););return t}(t,e);if(r){var o=Object.getOwnPropertyDescriptor(r,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}function er(t,e){return(er=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function nr(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=or(t);if(e){var o=or(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return rr(this,n)}}function rr(t,e){return!e||"object"!==Qn(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function or(t){return(or=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function ir(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function ar(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);nMath.abs(l.y),s.coords,s.rect),(0,j.default)(r,s.coords));return s.eventProps},defaults:{ratio:"preserve",equalDelta:!1,modifiers:[],enabled:!1}};function jr(t,e,n){var r=t.startCoords,o=t.edgeSign;e?n.y=r.y+(n.x-r.x)*o:n.x=r.x+(n.y-r.y)*o}function kr(t,e,n,r){var o=t.startRect,i=t.startCoords,a=t.ratio,s=t.edgeSign;if(e){var l=r.width/a;n.y=i.y+(l-o.height)*s}else{var u=r.height*a;n.x=i.x+(u-o.width)*s}}Pr.aspectRatio=Mr;var Ir=(0,ke.makeModifier)(Mr,"aspectRatio");Pr.default=Ir;var Dr={};Object.defineProperty(Dr,"__esModule",{value:!0}),Dr.default=void 0;var Ar=function(){};Ar._defaults={};var zr=Ar;Dr.default=zr;var Cr={};Object.defineProperty(Cr,"__esModule",{value:!0}),Object.defineProperty(Cr,"default",{enumerable:!0,get:function(){return Dr.default}});var Rr={};function Fr(t,e,n){return i.default.func(t)?k.resolveRectLike(t,e.interactable,e.element,[n.x,n.y,e]):k.resolveRectLike(t,e.interactable,e.element)}Object.defineProperty(Rr,"__esModule",{value:!0}),Rr.getRestrictionRect=Fr,Rr.restrict=Rr.default=void 0;var Xr={start:function(t){var e=t.rect,n=t.startOffset,r=t.state,o=t.interaction,i=t.pageCoords,a=r.options,s=a.elementRect,l=(0,j.default)({left:0,top:0,right:0,bottom:0},a.offset||{});if(e&&s){var u=Fr(a.restriction,o,i);if(u){var c=u.right-u.left-e.width,f=u.bottom-u.top-e.height;c<0&&(l.left+=c,l.right+=c),f<0&&(l.top+=f,l.bottom+=f)}l.left+=n.left-e.width*s.left,l.top+=n.top-e.height*s.top,l.right+=n.right-e.width*(1-s.right),l.bottom+=n.bottom-e.height*(1-s.bottom)}r.offset=l},set:function(t){var e=t.coords,n=t.interaction,r=t.state,o=r.options,i=r.offset,a=Fr(o.restriction,n,e);if(a){var s=k.xywhToTlbr(a);e.x=Math.max(Math.min(s.right-i.right,e.x),s.left+i.left),e.y=Math.max(Math.min(s.bottom-i.bottom,e.y),s.top+i.top)}},defaults:{restriction:null,elementRect:null,offset:null,endOnly:!1,enabled:!1}};Rr.restrict=Xr;var Yr=(0,ke.makeModifier)(Xr,"restrict");Rr.default=Yr;var Wr={};Object.defineProperty(Wr,"__esModule",{value:!0}),Wr.restrictEdges=Wr.default=void 0;var Lr={top:1/0,left:1/0,bottom:-1/0,right:-1/0},Br={top:-1/0,left:-1/0,bottom:1/0,right:1/0};function Ur(t,e){for(var n=["top","left","bottom","right"],r=0;rt.length)&&(e=t.length);for(var n=0,r=Array(e);n+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0,loaded_state:!1,restore_focus:!0,keyboard:{"ctrl-space":function(b){b.type="click",a(b.currentTarget).trigger(b)},enter:function(b){b.type="click",a(b.currentTarget).trigger(b)},left:function(b){if(b.preventDefault(),this.is_open(b.currentTarget))this.close_node(b.currentTarget);else{var c=this.get_parent(b.currentTarget);c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus()}},up:function(a){a.preventDefault();var b=this.get_prev_dom(a.currentTarget);b&&b.length&&b.children(".jstree-anchor").focus()},right:function(b){if(b.preventDefault(),this.is_closed(b.currentTarget))this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()});else if(this.is_open(b.currentTarget)){var c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0];c&&a(this._firstChild(c)).children(".jstree-anchor").focus()}},down:function(a){a.preventDefault();var b=this.get_next_dom(a.currentTarget);b&&b.length&&b.children(".jstree-anchor").focus()},"*":function(a){this.open_all()},home:function(b){b.preventDefault();var c=this._firstChild(this.get_container_ul()[0]);c&&a(c).children(".jstree-anchor").filter(":visible").focus()},end:function(a){a.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus()},f2:function(a){a.preventDefault(),this.edit(a.currentTarget)}}},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().outerHeight()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this.trigger("destroy"),this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},_create_prototype_node:function(){var a=i.createElement("LI"),b,c;return a.setAttribute("role","presentation"),b=i.createElement("I"),b.className="jstree-icon jstree-ocl",b.setAttribute("role","presentation"),a.appendChild(b),b=i.createElement("A"),b.className="jstree-anchor",b.setAttribute("href","#"),b.setAttribute("tabindex","-1"),b.setAttribute("role","treeitem"),c=i.createElement("I"),c.className="jstree-icon jstree-themeicon",c.setAttribute("role","presentation"),b.appendChild(c),a.appendChild(b),b=c=null,a},_kbevent_to_func:function(a){var b={8:"Backspace",9:"Tab",13:"Enter",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock",16:"Shift",17:"Ctrl",18:"Alt",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*",173:"-"},c=[];if(a.ctrlKey&&c.push("ctrl"),a.altKey&&c.push("alt"),a.shiftKey&&c.push("shift"),c.push(b[a.which]||a.which),c=c.sort().join("-").toLowerCase(),"shift-shift"===c||"ctrl-ctrl"===c||"alt-alt"===c)return null;var d=this.settings.core.keyboard,e,f;for(e in d)if(d.hasOwnProperty(e)&&(f=e,"-"!==f&&"+"!==f&&(f=f.replace("--","-MINUS").replace("+-","-MINUS").replace("++","-PLUS").replace("-+","-PLUS"),f=f.split(/-|\+/).sort().join("-").replace("MINUS","-").replace("PLUS","+").toLowerCase()),f===c))return d[e];return null},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;this._data.core.rtl&&(37===a.which?a.which=39:39===a.which&&(a.which=37));var b=this._kbevent_to_func(a);if(b){var c=b.call(this,a);if(c===!1||c===!0)return c}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this._data.core.themes.ellipsis=a.ellipsis,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"](),this[this._data.core.themes.ellipsis?"show_ellipsis":"hide_ellipsis"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").trigger("mouseleave"),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).trigger("mouseleave"),a(b.currentTarget).trigger("mouseenter"),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused&&this.settings.core.restore_focus){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(b){var c=this.settings.core.strings;return a.isFunction(c)?c.call(this,b):c&&c[b]?c[b]:b},_firstChild:function(a){a=a?a.firstChild:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_nextSibling:function(a){a=a?a.nextSibling:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_previousSibling:function(a){a=a?a.previousSibling:null;while(null!==a&&1!==a.nodeType)a=a.previousSibling;return a},get_node:function(b,c){b&&b.id&&(b=b.id),b instanceof a&&b.length&&b[0].id&&(b=b[0].id);var d;try{if(this._model.data[b])b=this._model.data[b];else if("string"==typeof b&&this._model.data[b.replace(/^#/,"")])b=this._model.data[b.replace(/^#/,"")];else if("string"==typeof b&&(d=a("#"+b.replace(a.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else if((d=this.element.find(b)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else{if(!(d=this.element.find(b)).length||!d.hasClass("jstree"))return!1;b=this._model.data[a.jstree.root]}return c&&(b=b.id===a.jstree.root?this.element:a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)),b}catch(e){return!1}},get_path:function(b,c,d){if(b=b.parents?b:this.get_node(b),!b||b.id===a.jstree.root||!b.parents)return!1;var e,f,g=[];for(g.push(d?b.id:b.text),e=0,f=b.parents.length;f>e;e++)g.push(d?b.parents[e]:this.get_text(b.parents[e]));return g=g.reverse().slice(1),c?g.join(c):g},get_next_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this._firstChild(this.get_container_ul()[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}if(b.hasClass("jstree-open")){d=this._firstChild(b.children(".jstree-children")[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);if(null!==d)return a(d)}d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return null!==d?a(d):b.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first()},get_prev_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this.get_container_ul()[0].lastChild;while(d&&0===d.offsetHeight)d=this._previousSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);if(null!==d){b=a(d);while(b.hasClass("jstree-open"))b=b.children(".jstree-children").first().children(".jstree-node:visible:last");return b}return d=b[0].parentNode.parentNode,d&&d.className&&-1!==d.className.indexOf("jstree-node")?a(d):!1},get_parent:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.parent:!1},get_children_dom:function(a){return a=this.get_node(a,!0),a[0]===this.element[0]?this.get_container_ul().children(".jstree-node"):a&&a.length?a.children(".jstree-children").children(".jstree-node"):!1},is_parent:function(a){return a=this.get_node(a),a&&(a.state.loaded===!1||a.children.length>0)},is_loaded:function(a){return a=this.get_node(a),a&&a.state.loaded},is_loading:function(a){return a=this.get_node(a),a&&a.state&&a.state.loading},is_open:function(a){return a=this.get_node(a),a&&a.state.opened},is_closed:function(a){return a=this.get_node(a),a&&this.is_parent(a)&&!a.state.opened},is_leaf:function(a){return!this.is_parent(a)},load_node:function(b,c){var d,e,f,g,h;if(a.isArray(b))return this._load_nodes(b.slice(),c),!0;if(b=this.get_node(b),!b)return c&&c.call(this,b,!1),!1;if(b.state.loaded){for(b.state.loaded=!1,f=0,g=b.parents.length;g>f;f++)this._model.data[b.parents[f]].children_d=a.vakata.array_filter(this._model.data[b.parents[f]].children_d,function(c){return-1===a.inArray(c,b.children_d)});for(d=0,e=b.children_d.length;e>d;d++)this._model.data[b.children_d[d]].state.selected&&(h=!0),delete this._model.data[b.children_d[d]];h&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(c){return-1===a.inArray(c,b.children_d)})),b.children=[],b.children_d=[],h&&this.trigger("changed",{action:"load_node",node:b,selected:this._data.core.selected})}return b.state.failed=!1,b.state.loading=!0,this.get_node(b,!0).addClass("jstree-loading").attr("aria-busy",!0),this._load_node(b,a.proxy(function(a){b=this._model.data[b.id],b.state.loading=!1,b.state.loaded=a,b.state.failed=!b.state.loaded;var d=this.get_node(b,!0),e=0,f=0,g=this._model.data,h=!1;for(e=0,f=b.children.length;f>e;e++)if(g[b.children[e]]&&!g[b.children[e]].state.hidden){h=!0;break}b.state.loaded&&d&&d.length&&(d.removeClass("jstree-closed jstree-open jstree-leaf"),h?"#"!==b.id&&d.addClass(b.state.opened?"jstree-open":"jstree-closed"):d.addClass("jstree-leaf")),d.removeClass("jstree-loading").attr("aria-busy",!1),this.trigger("load_node",{node:b,status:a}),c&&c.call(this,b,a)},this)),!0},_load_nodes:function(a,b,c,d){var e=!0,f=function(){this._load_nodes(a,b,!0)},g=this._model.data,h,i,j=[];for(h=0,i=a.length;i>h;h++)g[a[h]]&&(!g[a[h]].state.loaded&&!g[a[h]].state.failed||!c&&d)&&(this.is_loading(a[h])||this.load_node(a[h],f),e=!1);if(e){for(h=0,i=a.length;i>h;h++)g[a[h]]&&g[a[h]].state.loaded&&j.push(a[h]);b&&!b.done&&(b.call(this,j),b.done=!0)}},load_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=[],e=this._model.data,f=e[b.id].children_d,g,h;for(b.state&&!b.state.loaded&&d.push(b.id),g=0,h=f.length;h>g;g++)e[f[g]]&&e[f[g]].state&&!e[f[g]].state.loaded&&d.push(f[g]);d.length?this._load_nodes(d,function(){this.load_all(b,c)}):(c&&c.call(this,b),this.trigger("load_all",{node:b}))},_load_node:function(b,c){var d=this.settings.core.data,e,f=function g(){return 3!==this.nodeType&&8!==this.nodeType};return d?a.isFunction(d)?d.call(this,b,a.proxy(function(d){d===!1?c.call(this,!1):this["string"==typeof d?"_append_html_data":"_append_json_data"](b,"string"==typeof d?a(a.parseHTML(d)).filter(f):d,function(a){c.call(this,a)})},this)):"object"==typeof d?d.url?(d=a.extend(!0,{},d),a.isFunction(d.url)&&(d.url=d.url.call(this,b)),a.isFunction(d.data)&&(d.data=d.data.call(this,b)),a.ajax(d).done(a.proxy(function(d,e,g){var h=g.getResponseHeader("Content-Type");return h&&-1!==h.indexOf("json")||"object"==typeof d?this._append_json_data(b,d,function(a){c.call(this,a)}):h&&-1!==h.indexOf("html")||"string"==typeof d?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:g})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))},this)).fail(a.proxy(function(a){this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:a})},c.call(this,!1),this.settings.core.error.call(this,this._data.core.last_error)},this))):(e=a.isArray(d)?a.extend(!0,[],d):a.isPlainObject(d)?a.extend(!0,{},d):d,b.id===a.jstree.root?this._append_json_data(b,e,function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_05",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))):"string"==typeof d?b.id===a.jstree.root?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_06",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1)):c.call(this,!1):b.id===a.jstree.root?this._append_html_data(b,this._data.core.original_container_html.clone(!0),function(a){c.call(this,a)}):c.call(this,!1)},_node_changed:function(b){b=this.get_node(b),b&&-1===a.inArray(b.id,this._model.changed)&&this._model.changed.push(b.id)},_append_html_data:function(b,c,d){b=this.get_node(b),b.children=[],b.children_d=[];var e=c.is("ul")?c.children():c,f=b.id,g=[],h=[],i=this._model.data,j=i[f],k=this._data.core.selected.length,l,m,n;for(e.each(a.proxy(function(b,c){l=this._parse_model_from_html(a(c),f,j.parents.concat()),l&&(g.push(l),h.push(l),i[l].children_d.length&&(h=h.concat(i[l].children_d)))},this)),j.children=g,j.children_d=h,m=0,n=j.parents.length;n>m;m++)i[j.parents[m]].children_d=i[j.parents[m]].children_d.concat(h);this.trigger("model",{nodes:h,parent:f}),f!==a.jstree.root?(this._node_changed(f),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==k&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)},_append_json_data:function(b,c,d,e){if(null!==this.element){b=this.get_node(b),b.children=[],b.children_d=[],c.d&&(c=c.d,"string"==typeof c&&(c=JSON.parse(c))),a.isArray(c)||(c=[c]);var f=null,g={df:this._model.default_state,dat:c,par:b.id,m:this._model.data,t_id:this._id,t_cnt:this._cnt,sel:this._data.core.selected},h=this,i=function(a,b){a.data&&(a=a.data);var c=a.dat,d=a.par,e=[],f=[],g=[],i=a.df,j=a.t_id,k=a.t_cnt,l=a.m,m=l[d],n=a.sel,o,p,q,r,s=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f,h,j,k,m={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in i)i.hasOwnProperty(f)&&(m.state[f]=i[f]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(m.icon=a.data.jstree.icon),(m.icon===b||null===m.icon||""===m.icon)&&(m.icon=!0),a&&a.data&&(m.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(m.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(m.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(m.li_attr[f]=a.li_attr[f]);if(m.li_attr.id||(m.li_attr.id=e),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(m.a_attr[f]=a.a_attr[f]);for(a&&a.children&&a.children===!0&&(m.state.loaded=!1,m.children=[],m.children_d=[]),l[m.id]=m,f=0,h=m.children.length;h>f;f++)j=s(l[m.children[f]],m.id,d),k=l[j],m.children_d.push(j),k.children_d.length&&(m.children_d=m.children_d.concat(k.children_d));return delete a.data,delete a.children,l[m.id].original=a,m.state.selected&&g.push(m.id),m.id},t=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,h,m,n,o;do e="j"+j+"_"+ ++k;while(l[e]);o={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in i)i.hasOwnProperty(f)&&(o.state[f]=i[f]);if(a&&a.id&&(o.id=a.id.toString()),a&&a.text&&(o.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(o.icon=a.data.jstree.icon),(o.icon===b||null===o.icon||""===o.icon)&&(o.icon=!0),a&&a.data&&(o.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(o.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(o.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(o.li_attr[f]=a.li_attr[f]);if(o.li_attr.id&&!o.id&&(o.id=o.li_attr.id.toString()),o.id||(o.id=e),o.li_attr.id||(o.li_attr.id=o.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(o.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,h=a.children.length;h>f;f++)m=t(a.children[f],o.id,d),n=l[m],o.children.push(m),n.children_d.length&&(o.children_d=o.children_d.concat(n.children_d));o.children_d=o.children_d.concat(o.children)}return a&&a.children&&a.children===!0&&(o.state.loaded=!1,o.children=[],o.children_d=[]),delete a.data,delete a.children,o.original=a,l[o.id]=o,o.state.selected&&g.push(o.id),o.id};if(c.length&&c[0].id!==b&&c[0].parent!==b){for(p=0,q=c.length;q>p;p++)c[p].children||(c[p].children=[]),c[p].state||(c[p].state={}),l[c[p].id.toString()]=c[p];for(p=0,q=c.length;q>p;p++)l[c[p].parent.toString()]?(l[c[p].parent.toString()].children.push(c[p].id.toString()),m.children_d.push(c[p].id.toString())):"undefined"!=typeof h&&(h._data.core.last_error={error:"parse",plugin:"core",id:"core_07",reason:"Node with invalid parent",data:JSON.stringify({id:c[p].id.toString(),parent:c[p].parent.toString()})},h.settings.core.error.call(h,h._data.core.last_error));for(p=0,q=m.children.length;q>p;p++)o=s(l[m.children[p]],d,m.parents.concat()),f.push(o),l[o].children_d.length&&(f=f.concat(l[o].children_d));for(p=0,q=m.parents.length;q>p;p++)l[m.parents[p]].children_d=l[m.parents[p]].children_d.concat(f);r={cnt:k,mod:l,sel:n,par:d,dpc:f,add:g}}else{for(p=0,q=c.length;q>p;p++)o=t(c[p],d,m.parents.concat()),o&&(e.push(o),f.push(o),l[o].children_d.length&&(f=f.concat(l[o].children_d)));for(m.children=e,m.children_d=f,p=0,q=m.parents.length;q>p;p++)l[m.parents[p]].children_d=l[m.parents[p]].children_d.concat(f);r={cnt:k,mod:l,sel:n,par:d,dpc:f,add:g}}return"undefined"!=typeof window&&"undefined"!=typeof window.document?r:void postMessage(r)},k=function(b,c){if(null!==this.element){this._cnt=b.cnt;var e,f=this._model.data;for(e in f)f.hasOwnProperty(e)&&f[e].state&&f[e].state.loading&&b.mod[e]&&(b.mod[e].state.loading=!0);if(this._model.data=b.mod,c){var g,i=b.add,k=b.sel,l=this._data.core.selected.slice();if(f=this._model.data,k.length!==l.length||a.vakata.array_unique(k.concat(l)).length!==k.length){for(e=0,g=k.length;g>e;e++)-1===a.inArray(k[e],i)&&-1===a.inArray(k[e],l)&&(f[k[e]].state.selected=!1);for(e=0,g=l.length;g>e;e++)-1===a.inArray(l[e],k)&&(f[l[e]].state.selected=!0)}}b.add.length&&(this._data.core.selected=this._data.core.selected.concat(b.add)),this.trigger("model",{nodes:b.dpc,parent:b.par}),b.par!==a.jstree.root?(this._node_changed(b.par),this.redraw()):this.redraw(!0),b.add.length&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),!c&&j?j(function(){d.call(h,!0)}):d.call(h,!0)}};if(this.settings.core.worker&&window.Blob&&window.URL&&window.Worker)try{null===this._wrk&&(this._wrk=window.URL.createObjectURL(new window.Blob(["self.onmessage = "+i.toString()],{type:"text/javascript"}))),!this._data.core.working||e?(this._data.core.working=!0,f=new window.Worker(this._wrk),f.onmessage=a.proxy(function(a){k.call(this,a.data,!0);try{f.terminate(),f=null}catch(b){}this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1},this),g.par?f.postMessage(g):this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1):this._data.core.worker_queue.push([b,c,d,!0])}catch(l){k.call(this,i(g),!1),this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1}else k.call(this,i(g),!1)}},_parse_model_from_html:function(c,d,e){e=e?[].concat(e):[],d&&e.unshift(d);var f,g,h=this._model.data,i={id:!1,text:!1,icon:!0,parent:d,parents:e,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},j,k,l;for(j in this._model.default_state)this._model.default_state.hasOwnProperty(j)&&(i.state[j]=this._model.default_state[j]);if(k=a.vakata.attributes(c,!0),a.each(k,function(b,c){return c=a.trim(c),c.length?(i.li_attr[b]=c,void("id"===b&&(i.id=c.toString()))):!0}),k=c.children("a").first(),k.length&&(k=a.vakata.attributes(k,!0),a.each(k,function(b,c){c=a.trim(c),c.length&&(i.a_attr[b]=c)})),k=c.children("a").first().length?c.children("a").first().clone():c.clone(),k.children("ins, i, ul").remove(),k=k.html(),k=a("
    ").html(k),i.text=this.settings.core.force_text?k.text():k.html(),k=c.data(),i.data=k?a.extend(!0,{},k):null,i.state.opened=c.hasClass("jstree-open"),i.state.selected=c.children("a").hasClass("jstree-clicked"),i.state.disabled=c.children("a").hasClass("jstree-disabled"),i.data&&i.data.jstree)for(j in i.data.jstree)i.data.jstree.hasOwnProperty(j)&&(i.state[j]=i.data.jstree[j]);k=c.children("a").children(".jstree-themeicon"),k.length&&(i.icon=k.hasClass("jstree-themeicon-hidden")?!1:k.attr("rel")),i.state.icon!==b&&(i.icon=i.state.icon),(i.icon===b||null===i.icon||""===i.icon)&&(i.icon=!0),k=c.children("ul").children("li");do l="j"+this._id+"_"+ ++this._cnt;while(h[l]);return i.id=i.li_attr.id?i.li_attr.id.toString():l,k.length?(k.each(a.proxy(function(b,c){f=this._parse_model_from_html(a(c),i.id,e),g=this._model.data[f],i.children.push(f),g.children_d.length&&(i.children_d=i.children_d.concat(g.children_d))},this)),i.children_d=i.children_d.concat(i.children)):c.hasClass("jstree-closed")&&(i.state.loaded=!1),i.li_attr["class"]&&(i.li_attr["class"]=i.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),i.a_attr["class"]&&(i.a_attr["class"]=i.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),h[i.id]=i,i.state.selected&&this._data.core.selected.push(i.id),i.id},_parse_model_from_flat_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f=this._model.data,g=this._model.default_state,h,i,j,k,l={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(h in g)g.hasOwnProperty(h)&&(l.state[h]=g[h]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(h in a.data.jstree)a.data.jstree.hasOwnProperty(h)&&(l.state[h]=a.data.jstree[h]);if(a&&"object"==typeof a.state)for(h in a.state)a.state.hasOwnProperty(h)&&(l.state[h]=a.state[h]);if(a&&"object"==typeof a.li_attr)for(h in a.li_attr)a.li_attr.hasOwnProperty(h)&&(l.li_attr[h]=a.li_attr[h]);if(l.li_attr.id||(l.li_attr.id=e),a&&"object"==typeof a.a_attr)for(h in a.a_attr)a.a_attr.hasOwnProperty(h)&&(l.a_attr[h]=a.a_attr[h]);for(a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),f[l.id]=l,h=0,i=l.children.length;i>h;h++)j=this._parse_model_from_flat_json(f[l.children[h]],l.id,d),k=f[j],l.children_d.push(j),k.children_d.length&&(l.children_d=l.children_d.concat(k.children_d));return delete a.data,delete a.children,f[l.id].original=a,l.state.selected&&this._data.core.selected.push(l.id),l.id},_parse_model_from_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,g,h,i,j=this._model.data,k=this._model.default_state,l;do e="j"+this._id+"_"+ ++this._cnt;while(j[e]);l={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in k)k.hasOwnProperty(f)&&(l.state[f]=k[f]);if(a&&a.id&&(l.id=a.id.toString()),a&&a.text&&(l.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(l.state[f]=a.data.jstree[f]); +if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(l.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(l.li_attr[f]=a.li_attr[f]);if(l.li_attr.id&&!l.id&&(l.id=l.li_attr.id.toString()),l.id||(l.id=e),l.li_attr.id||(l.li_attr.id=l.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(l.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,g=a.children.length;g>f;f++)h=this._parse_model_from_json(a.children[f],l.id,d),i=j[h],l.children.push(h),i.children_d.length&&(l.children_d=l.children_d.concat(i.children_d));l.children_d=l.children.concat(l.children_d)}return a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),delete a.data,delete a.children,l.original=a,j[l.id]=l,l.state.selected&&this._data.core.selected.push(l.id),l.id},_redraw:function(){var b=this._model.force_full_redraw?this._model.data[a.jstree.root].children.concat([]):this._model.changed.concat([]),c=i.createElement("UL"),d,e,f,g=this._data.core.focused;for(e=0,f=b.length;f>e;e++)d=this.redraw_node(b[e],!0,this._model.force_full_redraw),d&&this._model.force_full_redraw&&c.appendChild(d);this._model.force_full_redraw&&(c.className=this.get_container_ul()[0].className,c.setAttribute("role","group"),this.element.empty().append(c)),null!==g&&this.settings.core.restore_focus&&(d=this.get_node(g,!0),d&&d.length&&d.children(".jstree-anchor")[0]!==i.activeElement?d.children(".jstree-anchor").focus():this._data.core.focused=null),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:b})},redraw:function(a){a&&(this._model.force_full_redraw=!0),this._redraw()},draw_children:function(b){var c=this.get_node(b),d=!1,e=!1,f=!1,g=i;if(!c)return!1;if(c.id===a.jstree.root)return this.redraw(!0);if(b=this.get_node(b,!0),!b||!b.length)return!1;if(b.children(".jstree-children").remove(),b=b[0],c.children.length&&c.state.loaded){for(f=g.createElement("UL"),f.setAttribute("role","group"),f.className="jstree-children",d=0,e=c.children.length;e>d;d++)f.appendChild(this.redraw_node(c.children[d],!0,!0));b.appendChild(f)}},redraw_node:function(b,c,d,e){var f=this.get_node(b),g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n="",o=i,p=this._model.data,q=!1,r=!1,s=null,t=0,u=0,v=!1,w=!1;if(!f)return!1;if(f.id===a.jstree.root)return this.redraw(!0);if(c=c||0===f.children.length,b=i.querySelector?this.element[0].querySelector("#"+(-1!=="0123456789".indexOf(f.id[0])?"\\3"+f.id[0]+" "+f.id.substr(1).replace(a.jstree.idregex,"\\$&"):f.id.replace(a.jstree.idregex,"\\$&"))):i.getElementById(f.id))b=a(b),d||(g=b.parent().parent()[0],g===this.element[0]&&(g=null),h=b.index()),c||!f.children.length||b.children(".jstree-children").length||(c=!0),c||(j=b.children(".jstree-children")[0]),q=b.children(".jstree-anchor")[0]===i.activeElement,b.remove();else if(c=!0,!d){if(g=f.parent!==a.jstree.root?a("#"+f.parent.replace(a.jstree.idregex,"\\$&"),this.element)[0]:null,!(null===g||g&&p[f.parent].state.opened))return!1;h=a.inArray(f.id,null===g?p[a.jstree.root].children:p[f.parent].children)}b=this._data.core.node.cloneNode(!0),n="jstree-node ";for(k in f.li_attr)if(f.li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"!==k?b.setAttribute(k,f.li_attr[k]):n+=f.li_attr[k]}for(f.a_attr.id||(f.a_attr.id=f.id+"_anchor"),b.setAttribute("aria-selected",!!f.state.selected),b.childNodes[1].setAttribute("aria-selected",!!f.state.selected),b.setAttribute("aria-level",f.parents.length),b.childNodes[1].setAttribute("aria-level",f.parents.length),b.setAttribute("aria-labelledby",f.a_attr.id),f.state.disabled&&(b.setAttribute("aria-disabled",!0),b.childNodes[1].setAttribute("aria-disabled",!0)),k=0,l=f.children.length;l>k;k++)if(!p[f.children[k]].state.hidden){v=!0;break}if(null!==f.parent&&p[f.parent]&&!f.state.hidden&&(k=a.inArray(f.id,p[f.parent].children),w=f.id,-1!==k))for(k++,l=p[f.parent].children.length;l>k;k++)if(p[p[f.parent].children[k]].state.hidden||(w=p[f.parent].children[k]),w!==f.id)break;f.state.hidden&&(n+=" jstree-hidden"),f.state.loading&&(n+=" jstree-loading"),f.state.loaded&&!v?n+=" jstree-leaf":(n+=f.state.opened&&f.state.loaded?" jstree-open":" jstree-closed",b.setAttribute("aria-expanded",f.state.opened&&f.state.loaded),b.childNodes[1].setAttribute("aria-expanded",f.state.opened&&f.state.loaded)),w===f.id&&(n+=" jstree-last"),b.id=f.id,b.className=n,n=(f.state.selected?" jstree-clicked":"")+(f.state.disabled?" jstree-disabled":"");for(l in f.a_attr)if(f.a_attr.hasOwnProperty(l)){if("href"===l&&"#"===f.a_attr[l])continue;"class"!==l?b.childNodes[1].setAttribute(l,f.a_attr[l]):n+=" "+f.a_attr[l]}if(n.length&&(b.childNodes[1].className="jstree-anchor "+n),(f.icon&&f.icon!==!0||f.icon===!1)&&(f.icon===!1?b.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===f.icon.indexOf("/")&&-1===f.icon.indexOf(".")?b.childNodes[1].childNodes[0].className+=" "+f.icon+" jstree-themeicon-custom":(b.childNodes[1].childNodes[0].style.backgroundImage='url("'+f.icon+'")',b.childNodes[1].childNodes[0].style.backgroundPosition="center center",b.childNodes[1].childNodes[0].style.backgroundSize="auto",b.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),this.settings.core.force_text?b.childNodes[1].appendChild(o.createTextNode(f.text)):b.childNodes[1].innerHTML+=f.text,c&&f.children.length&&(f.state.opened||e)&&f.state.loaded){for(m=o.createElement("UL"),m.setAttribute("role","group"),m.className="jstree-children",k=0,l=f.children.length;l>k;k++)m.appendChild(this.redraw_node(f.children[k],c,!0));b.appendChild(m)}if(j&&b.appendChild(j),!d){for(g||(g=this.element[0]),k=0,l=g.childNodes.length;l>k;k++)if(g.childNodes[k]&&g.childNodes[k].className&&-1!==g.childNodes[k].className.indexOf("jstree-children")){s=g.childNodes[k];break}s||(s=o.createElement("UL"),s.setAttribute("role","group"),s.className="jstree-children",g.appendChild(s)),g=s,hf;f++)this.open_node(c[f],d,e);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(e=e===b?this.settings.core.animation:e,this.is_closed(c)?this.is_loaded(c)?(h=this.get_node(c,!0),i=this,h.length&&(e&&h.children(".jstree-children").length&&h.children(".jstree-children").stop(!0,!0),c.children.length&&!this._firstChild(h.children(".jstree-children")[0])&&this.draw_children(c),e?(this.trigger("before_open",{node:c}),h.children(".jstree-children").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children(".jstree-anchor").attr("aria-expanded",!0).end().children(".jstree-children").stop(!0,!0).slideDown(e,function(){this.style.display="",i.element&&i.trigger("after_open",{node:c})})):(this.trigger("before_open",{node:c}),h[0].className=h[0].className.replace("jstree-closed","jstree-open"),h[0].setAttribute("aria-expanded",!0),h[0].childNodes[1].setAttribute("aria-expanded",!0))),c.state.opened=!0,d&&d.call(this,c,!0),h.length||this.trigger("before_open",{node:c}),this.trigger("open_node",{node:c}),e&&h.length||this.trigger("after_open",{node:c}),!0):this.is_loading(c)?setTimeout(a.proxy(function(){this.open_node(c,d,e)},this),500):void this.load_node(c,function(a,b){return b?this.open_node(a,d,e):d?d.call(this,a,!1):!1}):(d&&d.call(this,c,!1),!1)):!1},_open_to:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c,d,e=b.parents;for(c=0,d=e.length;d>c;c+=1)c!==a.jstree.root&&this.open_node(e[c],!1,0);return a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)},close_node:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.close_node(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?this.is_closed(c)?!1:(d=d===b?this.settings.core.animation:d,g=this,h=this.get_node(c,!0),c.state.opened=!1,this.trigger("close_node",{node:c}),void(h.length?d?h.children(".jstree-children").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children(".jstree-anchor").attr("aria-expanded",!1).end().children(".jstree-children").stop(!0,!0).slideUp(d,function(){this.style.display="",h.children(".jstree-children").remove(),g.element&&g.trigger("after_close",{node:c})}):(h[0].className=h[0].className.replace("jstree-open","jstree-closed"),h.children(".jstree-anchor").attr("aria-expanded",!1),h.attr("aria-expanded",!1).children(".jstree-children").remove(),this.trigger("after_close",{node:c})):this.trigger("after_close",{node:c}))):!1},toggle_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.toggle_node(b[c]);return!0}return this.is_closed(b)?this.open_node(b):this.is_open(b)?this.close_node(b):void 0},open_all:function(b,c,d){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var e=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),f,g,h;if(!e.length){for(f=0,g=b.children_d.length;g>f;f++)this.is_closed(this._model.data[b.children_d[f]])&&(this._model.data[b.children_d[f]].state.opened=!0);return this.trigger("open_all",{node:b})}d=d||e,h=this,e=this.is_closed(b)?e.find(".jstree-closed").addBack():e.find(".jstree-closed"),e.each(function(){h.open_node(this,function(a,b){b&&this.is_parent(a)&&this.open_all(a,c,d)},c||0)}),0===d.find(".jstree-closed").length&&this.trigger("open_all",{node:this.get_node(d)})},close_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),e=this,f,g;for(d.length&&(d=this.is_open(b)?d.find(".jstree-open").addBack():d.find(".jstree-open"),a(d.get().reverse()).each(function(){e.close_node(this,c||0)})),f=0,g=b.children_d.length;g>f;f++)this._model.data[b.children_d[f]].state.opened=!1;this.trigger("close_all",{node:b})},is_disabled:function(a){return a=this.get_node(a),a&&a.state&&a.state.disabled},enable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!1,this.get_node(b,!0).children(".jstree-anchor").removeClass("jstree-disabled").attr("aria-disabled",!1),void this.trigger("enable_node",{node:b})):!1},disable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!0,this.get_node(b,!0).children(".jstree-anchor").addClass("jstree-disabled").attr("aria-disabled",!0),void this.trigger("disable_node",{node:b})):!1},is_hidden:function(a){return a=this.get_node(a),a.state.hidden===!0},hide_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.hide_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden||(b.state.hidden=!0,this._node_changed(b.parent),c||this.redraw(),this.trigger("hide_node",{node:b}))):!1},show_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.show_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden&&(b.state.hidden=!1,this._node_changed(b.parent),c||this.redraw(),this.trigger("show_node",{node:b}))):!1},hide_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&!d[c].state.hidden&&(d[c].state.hidden=!0,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("hide_all",{nodes:e}),e},show_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&d[c].state.hidden&&(d[c].state.hidden=!1,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("show_all",{nodes:e}),e},activate_node:function(a,c){if(this.is_disabled(a))return!1;if(c&&"object"==typeof c||(c={}),this._data.core.last_clicked=this._data.core.last_clicked&&this._data.core.last_clicked.id!==b?this.get_node(this._data.core.last_clicked.id):null,this._data.core.last_clicked&&!this._data.core.last_clicked.state.selected&&(this._data.core.last_clicked=null),!this._data.core.last_clicked&&this._data.core.selected.length&&(this._data.core.last_clicked=this.get_node(this._data.core.selected[this._data.core.selected.length-1])),this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&(!c.shiftKey||this._data.core.last_clicked&&this.get_parent(a)&&this.get_parent(a)===this._data.core.last_clicked.parent))if(c.shiftKey){var d=this.get_node(a).id,e=this._data.core.last_clicked.id,f=this.get_node(this._data.core.last_clicked.parent).children,g=!1,h,i;for(h=0,i=f.length;i>h;h+=1)f[h]===d&&(g=!g),f[h]===e&&(g=!g),this.is_disabled(f[h])||!g&&f[h]!==d&&f[h]!==e?this.deselect_node(f[h],!0,c):this.is_hidden(f[h])||this.select_node(f[h],!0,!1,c);this.trigger("changed",{action:"select_node",node:this.get_node(a),selected:this._data.core.selected,event:c})}else this.is_selected(a)?this.deselect_node(a,!1,c):this.select_node(a,!1,!1,c);else!this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&this.is_selected(a)?this.deselect_node(a,!1,c):(this.deselect_all(!0),this.select_node(a,!1,!1,c),this._data.core.last_clicked=this.get_node(a));this.trigger("activate_node",{node:this.get_node(a),event:c})},hover_node:function(a){if(a=this.get_node(a,!0),!a||!a.length||a.children(".jstree-hovered").length)return!1;var b=this.element.find(".jstree-hovered"),c=this.element;b&&b.length&&this.dehover_node(b),a.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(a)}),setTimeout(function(){c.attr("aria-activedescendant",a[0].id)},0)},dehover_node:function(a){return a=this.get_node(a,!0),a&&a.length&&a.children(".jstree-hovered").length?(a.children(".jstree-anchor").removeClass("jstree-hovered"),void this.trigger("dehover_node",{node:this.get_node(a)})):!1},select_node:function(b,c,d,e){var f,g,h,i;if(a.isArray(b)){for(b=b.slice(),g=0,h=b.length;h>g;g++)this.select_node(b[g],c,d,e);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.selected||(b.state.selected=!0,this._data.core.selected.push(b.id),d||(f=this._open_to(b)),f&&f.length&&f.attr("aria-selected",!0).children(".jstree-anchor").addClass("jstree-clicked").attr("aria-selected",!0),this.trigger("select_node",{node:b,selected:this._data.core.selected,event:e}),c||this.trigger("changed",{action:"select_node",node:b,selected:this._data.core.selected,event:e})))):!1},deselect_node:function(b,c,d){var e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.deselect_node(b[e],c,d);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(g=this.get_node(b,!0),void(b.state.selected&&(b.state.selected=!1,this._data.core.selected=a.vakata.array_remove_item(this._data.core.selected,b.id),g.length&&g.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-clicked").attr("aria-selected",!1),this.trigger("deselect_node",{node:b,selected:this._data.core.selected,event:d}),c||this.trigger("changed",{action:"deselect_node",node:b,selected:this._data.core.selected,event:d})))):!1},select_all:function(b){var c=this._data.core.selected.concat([]),d,e;for(this._data.core.selected=this._model.data[a.jstree.root].children_d.concat(),d=0,e=this._data.core.selected.length;e>d;d++)this._model.data[this._data.core.selected[d]]&&(this._model.data[this._data.core.selected[d]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),b||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:c})},deselect_all:function(a){var b=this._data.core.selected.concat([]),c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)this._model.data[this._data.core.selected[c]]&&(this._model.data[this._data.core.selected[c]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked").attr("aria-selected",!1).parent().attr("aria-selected",!1),this.trigger("deselect_all",{selected:this._data.core.selected,node:b}),a||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:b})},is_selected:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.selected:!1},get_selected:function(b){return b?a.map(this._data.core.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.core.selected.slice()},get_top_selected:function(b){var c=this.get_selected(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},get_bottom_selected:function(b){var c=this.get_selected(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},get_state:function(){var b={core:{open:[],loaded:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},c;for(c in this._model.data)this._model.data.hasOwnProperty(c)&&c!==a.jstree.root&&(this._model.data[c].state.loaded&&this.settings.core.loaded_state&&b.core.loaded.push(c),this._model.data[c].state.opened&&b.core.open.push(c),this._model.data[c].state.selected&&b.core.selected.push(c));return b},set_state:function(c,d){if(c){if(c.core&&c.core.selected&&c.core.initial_selection===b&&(c.core.initial_selection=this._data.core.selected.concat([]).sort().join(",")),c.core){var e,f,g,h,i;if(c.core.loaded)return this.settings.core.loaded_state&&a.isArray(c.core.loaded)&&c.core.loaded.length?this._load_nodes(c.core.loaded,function(a){delete c.core.loaded,this.set_state(c,d)}):(delete c.core.loaded,this.set_state(c,d)),!1;if(c.core.open)return a.isArray(c.core.open)&&c.core.open.length?this._load_nodes(c.core.open,function(a){this.open_node(a,!1,0),delete c.core.open,this.set_state(c,d)}):(delete c.core.open,this.set_state(c,d)),!1;if(c.core.scroll)return c.core.scroll&&c.core.scroll.left!==b&&this.element.scrollLeft(c.core.scroll.left),c.core.scroll&&c.core.scroll.top!==b&&this.element.scrollTop(c.core.scroll.top),delete c.core.scroll,this.set_state(c,d),!1;if(c.core.selected)return h=this,(c.core.initial_selection===b||c.core.initial_selection===this._data.core.selected.concat([]).sort().join(","))&&(this.deselect_all(),a.each(c.core.selected,function(a,b){h.select_node(b,!1,!0)})),delete c.core.initial_selection,delete c.core.selected,this.set_state(c,d),!1;for(i in c)c.hasOwnProperty(i)&&"core"!==i&&-1===a.inArray(i,this.settings.plugins)&&delete c[i];if(a.isEmptyObject(c.core))return delete c.core,this.set_state(c,d),!1}return a.isEmptyObject(c)?(c=null,d&&d.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(b,c){this._data.core.state=c===!0?{}:this.get_state(),c&&a.isFunction(c)&&(this._data.core.state=c.call(this,this._data.core.state)),this._cnt=0,this._model.data={},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this._data.core.selected=[],this._data.core.last_clicked=null,this._data.core.focused=null;var d=this.get_container_ul()[0].className;b||(this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(a.jstree.root,function(b,c){c&&(this.get_container_ul()[0].className=d,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(a.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c=[],d=[],e=this._data.core.selected.concat([]);d.push(b.id),b.state.opened===!0&&c.push(b.id),this.get_node(b,!0).find(".jstree-open").each(function(){d.push(this.id),c.push(this.id)}),this._load_nodes(d,a.proxy(function(a){this.open_node(c,!1,0),this.select_node(e),this.trigger("refresh_node",{node:b,nodes:a})},this),!1,!0)},set_id:function(b,c){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var d,e,f=this._model.data,g=b.id;for(c=c.toString(),f[b.parent].children[a.inArray(b.id,f[b.parent].children)]=c,d=0,e=b.parents.length;e>d;d++)f[b.parents[d]].children_d[a.inArray(b.id,f[b.parents[d]].children_d)]=c;for(d=0,e=b.children.length;e>d;d++)f[b.children[d]].parent=c;for(d=0,e=b.children_d.length;e>d;d++)f[b.children_d[d]].parents[a.inArray(b.id,f[b.children_d[d]].parents)]=c;return d=a.inArray(b.id,this._data.core.selected),-1!==d&&(this._data.core.selected[d]=c),d=this.get_node(b.id,!0),d&&(d.attr("id",c),this.element.attr("aria-activedescendant")===b.id&&this.element.attr("aria-activedescendant",c)),delete f[b.id],b.id=c,b.li_attr.id=c,f[c]=b,this.trigger("set_id",{node:b,"new":b.id,old:g}),!0},get_text:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.text:!1},set_text:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.set_text(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.text=c,this.get_node(b,!0).length&&this.redraw_node(b.id),this.trigger("set_text",{obj:b,text:c}),!0):!1},get_json:function(b,c,d){if(b=this.get_node(b||a.jstree.root),!b)return!1;c&&c.flat&&!d&&(d=[]);var e={id:b.id,text:b.text,icon:this.get_icon(b),li_attr:a.extend(!0,{},b.li_attr),a_attr:a.extend(!0,{},b.a_attr),state:{},data:c&&c.no_data?!1:a.extend(!0,a.isArray(b.data)?[]:{},b.data)},f,g;if(c&&c.flat?e.parent=b.parent:e.children=[],c&&c.no_state)delete e.state;else for(f in b.state)b.state.hasOwnProperty(f)&&(e.state[f]=b.state[f]);if(c&&c.no_li_attr&&delete e.li_attr,c&&c.no_a_attr&&delete e.a_attr,c&&c.no_id&&(delete e.id,e.li_attr&&e.li_attr.id&&delete e.li_attr.id,e.a_attr&&e.a_attr.id&&delete e.a_attr.id),c&&c.flat&&b.id!==a.jstree.root&&d.push(e),!c||!c.no_children)for(f=0,g=b.children.length;g>f;f++)c&&c.flat?this.get_json(b.children[f],c,d):e.children.push(this.get_json(b.children[f],c));return c&&c.flat?d:b.id===a.jstree.root?e.children:e},create_node:function(c,d,e,f,g){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return!1;if(e=e===b?"last":e,!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(c))return this.load_node(c,function(){this.create_node(c,d,e,f,!0)});d||(d={text:this.get_string("New node")}),d="string"==typeof d?{text:d}:a.extend(!0,{},d),d.text===b&&(d.text=this.get_string("New node"));var h,i,j,k;switch(c.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":h=this.get_node(c.parent),e=a.inArray(c.id,h.children),c=h;break;case"after":h=this.get_node(c.parent),e=a.inArray(c.id,h.children)+1,c=h;break;case"inside":case"first":e=0;break;case"last":e=c.children.length;break;default:e||(e=0)}if(e>c.children.length&&(e=c.children.length),d.id||(d.id=!0),!this.check("create_node",d,c,e))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(d.id===!0&&delete d.id,d=this._parse_model_from_json(d,c.id,c.parents.concat()),!d)return!1;for(h=this.get_node(d),i=[],i.push(d),i=i.concat(h.children_d),this.trigger("model",{nodes:i,parent:c.id}),c.children_d=c.children_d.concat(i),j=0,k=c.parents.length;k>j;j++)this._model.data[c.parents[j]].children_d=this._model.data[c.parents[j]].children_d.concat(i);for(d=h,h=[],j=0,k=c.children.length;k>j;j++)h[j>=e?j+1:j]=c.children[j];return h[e]=d.id,c.children=h,this.redraw_node(c,!0),this.trigger("create_node",{node:this.get_node(d),parent:c.id,position:e}),f&&f.call(this,this.get_node(d)),d.id},rename_node:function(b,c){var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.rename_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=b.text,this.check("rename_node",b,this.get_parent(b),c)?(this.set_text(b,c),this.trigger("rename_node",{node:b,text:c,old:f}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.delete_node(b[c]);return!0}if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;if(e=this.get_node(b.parent),f=a.inArray(b.id,e.children),l=!1,!this.check("delete_node",b,e,f))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==f&&(e.children=a.vakata.array_remove(e.children,f)),g=b.children_d.concat([]),g.push(b.id),h=0,i=b.parents.length;i>h;h++)this._model.data[b.parents[h]].children_d=a.vakata.array_filter(this._model.data[b.parents[h]].children_d,function(b){return-1===a.inArray(b,g)});for(j=0,k=g.length;k>j;j++)if(this._model.data[g[j]].state.selected){l=!0;break}for(l&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(b){return-1===a.inArray(b,g)})),this.trigger("delete_node",{node:b,parent:e.id}),l&&this.trigger("changed",{action:"delete_node",node:b,selected:this._data.core.selected,parent:e.id}),j=0,k=g.length;k>j;j++)delete this._model.data[g[j]];return-1!==a.inArray(this._data.core.focused,g)&&(this._data.core.focused=null,m=this.element[0].scrollTop,n=this.element[0].scrollLeft,e.id===a.jstree.root?this._model.data[a.jstree.root].children[0]&&this.get_node(this._model.data[a.jstree.root].children[0],!0).children(".jstree-anchor").focus():this.get_node(e,!0).children(".jstree-anchor").focus(),this.element[0].scrollTop=m,this.element[0].scrollLeft=n),this.redraw_node(e,!0),!0},check:function(b,c,d,e,f){c=c&&c.id?c:this.get_node(c),d=d&&d.id?d:this.get_node(d);var g=b.match(/^move_node|copy_node|create_node$/i)?d:c,h=this.settings.core.check_callback;if("move_node"===b||"copy_node"===b){if(!(f&&f.is_multi||"move_node"!==b||a.inArray(c.id,d.children)!==e))return this._data.core.last_error={error:"check",plugin:"core",id:"core_08",reason:"Moving node to its current position",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1;if(!(f&&f.is_multi||c.id!==d.id&&("move_node"!==b||a.inArray(c.id,d.children)!==e)&&-1===a.inArray(d.id,c.children_d)))return this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1}return g&&g.data&&(g=g.data),g&&g.functions&&(g.functions[b]===!1||g.functions[b]===!0)?(g.functions[b]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})}),g.functions[b]):h===!1||a.isFunction(h)&&h.call(this,b,c,d,e,f)===!1||h&&h[b]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1):!0},last_error:function(){return this._data.core.last_error},move_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.move_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(r=this.move_node(c[j],d,e,f,g,!1,i))&&(d=r,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;if(l=(c.parent||a.jstree.root).toString(),n=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,o=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),p=!o||!o._id||this._id!==o._id,m=o&&o._id&&l&&o._model.data[l]&&o._model.data[l].children?a.inArray(c.id,o._model.data[l].children):-1,o&&o._id&&(c=o._model.data[c.id]),p)return(r=this.copy_node(c,d,e,f,g,!1,i))?(o&&o.delete_node(c),r):!1;switch(d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,n.children);break;case"after":e=a.inArray(d.id,n.children)+1;break;case"inside":case"first":e=0;break;case"last":e=n.children.length;break;default:e||(e=0)}if(e>n.children.length&&(e=n.children.length),!this.check("move_node",c,n,e,{core:!0,origin:i,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(c.parent===n.id){for(q=n.children.concat(),r=a.inArray(c.id,q),-1!==r&&(q=a.vakata.array_remove(q,r),e>r&&e--),r=[],s=0,t=q.length;t>s;s++)r[s>=e?s+1:s]=q[s];r[e]=c.id,n.children=r,this._node_changed(n.id),this.redraw(n.id===a.jstree.root)}else{for(r=c.children_d.concat(),r.push(c.id),s=0,t=c.parents.length;t>s;s++){for(q=[],w=o._model.data[c.parents[s]].children_d,u=0,v=w.length;v>u;u++)-1===a.inArray(w[u],r)&&q.push(w[u]);o._model.data[c.parents[s]].children_d=q}for(o._model.data[l].children=a.vakata.array_remove_item(o._model.data[l].children,c.id),s=0,t=n.parents.length;t>s;s++)this._model.data[n.parents[s]].children_d=this._model.data[n.parents[s]].children_d.concat(r);for(q=[],s=0,t=n.children.length;t>s;s++)q[s>=e?s+1:s]=n.children[s];for(q[e]=c.id,n.children=q,n.children_d.push(c.id),n.children_d=n.children_d.concat(c.children_d),c.parent=n.id,r=n.parents.concat(),r.unshift(n.id),w=c.parents.length,c.parents=r,r=r.concat(),s=0,t=c.children_d.length;t>s;s++)this._model.data[c.children_d[s]].parents=this._model.data[c.children_d[s]].parents.slice(0,-1*w),Array.prototype.push.apply(this._model.data[c.children_d[s]].parents,r);(l===a.jstree.root||n.id===a.jstree.root)&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||(this._node_changed(l),this._node_changed(n.id)),h||this.redraw()}return f&&f.call(this,c,n,e),this.trigger("move_node",{node:c,parent:n.id,position:e,old_parent:l,old_position:m,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id,old_instance:o,new_instance:this}),c.id},copy_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.copy_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(m=this.copy_node(c[j],d,e,f,g,!0,i))&&(d=m,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;switch(q=(c.parent||a.jstree.root).toString(),r=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,s=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),t=!s||!s._id||this._id!==s._id,s&&s._id&&(c=s._model.data[c.id]),d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,r.children);break;case"after":e=a.inArray(d.id,r.children)+1;break;case"inside":case"first":e=0;break;case"last":e=r.children.length;break;default:e||(e=0)}if(e>r.children.length&&(e=r.children.length),!this.check("copy_node",c,r,e,{core:!0,origin:i,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(p=s?s.get_json(c,{no_id:!0,no_data:!0,no_state:!0}):c,!p)return!1;if(p.id===!0&&delete p.id,p=this._parse_model_from_json(p,r.id,r.parents.concat()), +!p)return!1;for(m=this.get_node(p),c&&c.state&&c.state.loaded===!1&&(m.state.loaded=!1),l=[],l.push(p),l=l.concat(m.children_d),this.trigger("model",{nodes:l,parent:r.id}),n=0,o=r.parents.length;o>n;n++)this._model.data[r.parents[n]].children_d=this._model.data[r.parents[n]].children_d.concat(l);for(l=[],n=0,o=r.children.length;o>n;n++)l[n>=e?n+1:n]=r.children[n];return l[e]=m.id,r.children=l,r.children_d.push(m.id),r.children_d=r.children_d.concat(m.children_d),r.id===a.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(r.id),h||this.redraw(r.id===a.jstree.root),f&&f.call(this,m,r,e),this.trigger("copy_node",{node:m,original:c,parent:r.id,position:e,old_parent:q,old_position:s&&s._id&&q&&s._model.data[q]&&s._model.data[q].children?a.inArray(c.id,s._model.data[q].children):-1,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id,old_instance:s,new_instance:this}),m.id},cut:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="move_node",void this.trigger("cut",{node:b})):!1},copy:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="copy_node",void this.trigger("copy",{node:b})):!1},get_buffer:function(){return{mode:e,node:d,inst:f}},can_paste:function(){return e!==!1&&d!==!1},paste:function(a,b){return a=this.get_node(a),a&&e&&e.match(/^(copy_node|move_node)$/)&&d?(this[e](d,a,b,!1,!1,!1,f)&&this.trigger("paste",{parent:a.id,node:d,mode:e}),d=!1,e=!1,void(f=!1)):!1},clear_buffer:function(){d=!1,e=!1,f=!1,this.trigger("clear_buffer")},edit:function(b,c,d){var e,f,g,h,j,k,l,m,n,o=!1;return(b=this.get_node(b))?this.check("edit",b,this.get_parent(b))?(n=b,c="string"==typeof c?c:b.text,this.set_text(b,""),b=this._open_to(b),n.text=c,e=this._data.core.rtl,f=this.element.width(),this._data.core.focused=n.id,g=b.children(".jstree-anchor").focus(),h=a(""),j=c,k=a("
    ",{css:{position:"absolute",top:"-200px",left:e?"0px":"-1000px",visibility:"hidden"}}).appendTo(i.body),l=a("",{value:j,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:a.proxy(function(c){c.stopImmediatePropagation(),c.preventDefault();var e=h.children(".jstree-rename-input"),f=e.val(),i=this.settings.core.force_text,m;""===f&&(f=j),k.remove(),h.replaceWith(g),h.remove(),j=i?j:a("
    ").append(a.parseHTML(j)).html(),b=this.get_node(b),this.set_text(b,j),m=!!this.rename_node(b,i?a("
    ").text(f).text():a("
    ").append(a.parseHTML(f)).html()),m||this.set_text(b,j),this._data.core.focused=n.id,setTimeout(a.proxy(function(){var a=this.get_node(n.id,!0);a.length&&(this._data.core.focused=n.id,a.children(".jstree-anchor").focus())},this),0),d&&d.call(this,n,m,o),l=null},this),keydown:function(a){var b=a.which;27===b&&(o=!0,this.value=j),(27===b||13===b||37===b||38===b||39===b||40===b||32===b)&&a.stopImmediatePropagation(),(27===b||13===b)&&(a.preventDefault(),this.blur())},click:function(a){a.stopImmediatePropagation()},mousedown:function(a){a.stopImmediatePropagation()},keyup:function(a){l.width(Math.min(k.text("pW"+this.value).width(),f))},keypress:function(a){return 13===a.which?!1:void 0}}),m={fontFamily:g.css("fontFamily")||"",fontSize:g.css("fontSize")||"",fontWeight:g.css("fontWeight")||"",fontStyle:g.css("fontStyle")||"",fontStretch:g.css("fontStretch")||"",fontVariant:g.css("fontVariant")||"",letterSpacing:g.css("letterSpacing")||"",wordSpacing:g.css("wordSpacing")||""},h.attr("class",g.attr("class")).append(g.contents().clone()).append(l),g.replaceWith(h),k.css(m),l.css(m).width(Math.min(k.text("pW"+l[0].value).width(),f))[0].select(),void a(i).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(b){l&&b.target!==l&&a(l).blur()})):(this.settings.core.error.call(this,this._data.core.last_error),!1):!1},set_theme:function(b,c){if(!b)return!1;if(c===!0){var d=this.settings.core.themes.dir;d||(d=a.jstree.path+"/themes"),c=d+"/"+b+"/style.css"}c&&-1===a.inArray(c,g)&&(a("head").append(''),g.push(c)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=b,this.element.addClass("jstree-"+b),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+b+"-responsive"),this.trigger("set_theme",{theme:b})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(a){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=a,a&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped"),this.trigger("show_stripes")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped"),this.trigger("hide_stripes")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots"),this.trigger("show_dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots"),this.trigger("hide_dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons"),this.trigger("show_icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons"),this.trigger("hide_icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},show_ellipsis:function(){this._data.core.themes.ellipsis=!0,this.get_container_ul().addClass("jstree-ellipsis"),this.trigger("show_ellipsis")},hide_ellipsis:function(){this._data.core.themes.ellipsis=!1,this.get_container_ul().removeClass("jstree-ellipsis"),this.trigger("hide_ellipsis")},toggle_ellipsis:function(){this._data.core.themes.ellipsis?this.hide_ellipsis():this.show_ellipsis()},set_icon:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.set_icon(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(h=c.icon,c.icon=d===!0||null===d||d===b||""===d?!0:d,g=this.get_node(c,!0).children(".jstree-anchor").children(".jstree-themeicon"),d===!1?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),this.hide_icon(c)):d===!0||null===d||d===b||""===d?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),h===!1&&this.show_icon(c)):-1===d.indexOf("/")&&-1===d.indexOf(".")?(g.removeClass(h).css("background",""),g.addClass(d+" jstree-themeicon-custom").attr("rel",d),h===!1&&this.show_icon(c)):(g.removeClass(h).css("background",""),g.addClass("jstree-themeicon-custom").css("background","url('"+d+"') center center no-repeat").attr("rel",d),h===!1&&this.show_icon(c)),!0):!1},get_icon:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.icon:!1},hide_icon:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.hide_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(b.icon=!1,this.get_node(b,!0).children(".jstree-anchor").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.show_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(e=this.get_node(b,!0),b.icon=e.length?e.children(".jstree-anchor").children(".jstree-themeicon").attr("rel"):!0,b.icon||(b.icon=!0),e.children(".jstree-anchor").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},a.vakata={},a.vakata.attributes=function(b,c){b=a(b)[0];var d=c?{}:[];return b&&b.attributes&&a.each(b.attributes,function(b,e){-1===a.inArray(e.name.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==e.value&&""!==a.trim(e.value)&&(c?d[e.name]=e.value:d.push(e.name))}),d},a.vakata.array_unique=function(a){var c=[],d,e,f,g={};for(d=0,f=a.length;f>d;d++)g[a[d]]===b&&(c.push(a[d]),g[a[d]]=!0);return c},a.vakata.array_remove=function(a,b){return a.splice(b,1),a},a.vakata.array_remove_item=function(b,c){var d=a.inArray(c,b);return-1!==d?a.vakata.array_remove(b,d):b},a.vakata.array_filter=function(a,b,c,d,e){if(a.filter)return a.filter(b,c);d=[];for(e in a)~~e+""==e+""&&e>=0&&b.call(c,a[e],+e,a)&&d.push(a[e]);return d},a.jstree.plugins.changed=function(a,b){var c=[];this.trigger=function(a,d){var e,f;if(d||(d={}),"changed"===a.replace(".jstree","")){d.changed={selected:[],deselected:[]};var g={};for(e=0,f=c.length;f>e;e++)g[c[e]]=1;for(e=0,f=d.selected.length;f>e;e++)g[d.selected[e]]?g[d.selected[e]]=2:d.changed.selected.push(d.selected[e]);for(e=0,f=c.length;f>e;e++)1===g[c[e]]&&d.changed.deselected.push(c[e]);c=d.selected.slice()}b.trigger.call(this,a,d)},this.refresh=function(a,d){return c=[],b.refresh.apply(this,arguments)}};var l=i.createElement("I");l.className="jstree-icon jstree-checkbox",l.setAttribute("role","presentation"),a.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0,cascade:"",tie_selection:!0,cascade_to_disabled:!0,cascade_to_hidden:!0},a.jstree.plugins.checkbox=function(c,d){this.bind=function(){d.bind.call(this),this._data.checkbox.uto=!1,this._data.checkbox.selected=[],this.settings.checkbox.three_state&&(this.settings.checkbox.cascade="up+down+undetermined"),this.element.on("init.jstree",a.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked"),this.settings.checkbox.tie_selection&&this.element.addClass("jstree-checkbox-selection")},this)).on("loading.jstree",a.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),-1!==this.settings.checkbox.cascade.indexOf("undetermined")&&this.element.on("changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",a.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)},this)),this.settings.checkbox.tie_selection||this.element.on("model.jstree",a.proxy(function(a,b){var c=this._model.data,d=c[b.parent],e=b.nodes,f,g;for(f=0,g=e.length;g>f;f++)c[e[f]].state.checked=c[e[f]].state.checked||c[e[f]].original&&c[e[f]].original.state&&c[e[f]].original.state.checked,c[e[f]].state.checked&&this._data.checkbox.selected.push(e[f])},this)),(-1!==this.settings.checkbox.cascade.indexOf("up")||-1!==this.settings.checkbox.cascade.indexOf("down"))&&this.element.on("model.jstree",a.proxy(function(b,c){var d=this._model.data,e=d[c.parent],f=c.nodes,g=[],h,i,j,k,l,m,n=this.settings.checkbox.cascade,o=this.settings.checkbox.tie_selection;if(-1!==n.indexOf("down"))if(e.state[o?"selected":"checked"]){for(i=0,j=f.length;j>i;i++)d[f[i]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(f)}else for(i=0,j=f.length;j>i;i++)if(d[f[i]].state[o?"selected":"checked"]){for(k=0,l=d[f[i]].children_d.length;l>k;k++)d[d[f[i]].children_d[k]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(d[f[i]].children_d)}if(-1!==n.indexOf("up")){for(i=0,j=e.children_d.length;j>i;i++)d[e.children_d[i]].children.length||g.push(d[e.children_d[i]].parent);for(g=a.vakata.array_unique(g),k=0,l=g.length;l>k;k++){e=d[g[k]];while(e&&e.id!==a.jstree.root){for(h=0,i=0,j=e.children.length;j>i;i++)h+=d[e.children[i]].state[o?"selected":"checked"];if(h!==j)break;e.state[o?"selected":"checked"]=!0,this._data[o?"core":"checkbox"].selected.push(e.id),m=this.get_node(e,!0),m&&m.length&&m.attr("aria-selected",!0).children(".jstree-anchor").addClass(o?"jstree-clicked":"jstree-checked"),e=this.get_node(e.parent)}}}this._data[o?"core":"checkbox"].selected=a.vakata.array_unique(this._data[o?"core":"checkbox"].selected)},this)).on(this.settings.checkbox.tie_selection?"select_node.jstree":"check_node.jstree",a.proxy(function(b,c){var d=this,e=c.node,f=this._model.data,g=this.get_node(e.parent),h,i,j,k,l=this.settings.checkbox.cascade,m=this.settings.checkbox.tie_selection,n={},o=this._data[m?"core":"checkbox"].selected;for(h=0,i=o.length;i>h;h++)n[o[h]]=!0;if(-1!==l.indexOf("down")){var p=this._cascade_new_checked_state(e.id,!0),q=e.children_d.concat(e.id);for(h=0,i=q.length;i>h;h++)p.indexOf(q[h])>-1?n[q[h]]=!0:delete n[q[h]]}if(-1!==l.indexOf("up"))while(g&&g.id!==a.jstree.root){for(j=0,h=0,i=g.children.length;i>h;h++)j+=f[g.children[h]].state[m?"selected":"checked"];if(j!==i)break;g.state[m?"selected":"checked"]=!0,n[g.id]=!0,k=this.get_node(g,!0),k&&k.length&&k.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),g=this.get_node(g.parent)}o=[];for(h in n)n.hasOwnProperty(h)&&o.push(h);this._data[m?"core":"checkbox"].selected=o},this)).on(this.settings.checkbox.tie_selection?"deselect_all.jstree":"uncheck_all.jstree",a.proxy(function(b,c){var d=this.get_node(a.jstree.root),e=this._model.data,f,g,h;for(f=0,g=d.children_d.length;g>f;f++)h=e[d.children_d[f]],h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1)},this)).on(this.settings.checkbox.tie_selection?"deselect_node.jstree":"uncheck_node.jstree",a.proxy(function(b,c){var d=this,e=c.node,f=this.get_node(e,!0),g,h,i,j=this.settings.checkbox.cascade,k=this.settings.checkbox.tie_selection,l=this._data[k?"core":"checkbox"].selected,m={},n=[],o=e.children_d.concat(e.id);if(-1!==j.indexOf("down")){var p=this._cascade_new_checked_state(e.id,!1);l=a.vakata.array_filter(l,function(a){return-1===o.indexOf(a)||p.indexOf(a)>-1})}if(-1!==j.indexOf("up")&&-1===l.indexOf(e.id)){for(g=0,h=e.parents.length;h>g;g++)i=this._model.data[e.parents[g]],i.state[k?"selected":"checked"]=!1,i&&i.original&&i.original.state&&i.original.state.undetermined&&(i.original.state.undetermined=!1),i=this.get_node(e.parents[g],!0),i&&i.length&&i.attr("aria-selected",!1).children(".jstree-anchor").removeClass(k?"jstree-clicked":"jstree-checked");l=a.vakata.array_filter(l,function(a){return-1===e.parents.indexOf(a)})}this._data[k?"core":"checkbox"].selected=l},this)),-1!==this.settings.checkbox.cascade.indexOf("up")&&this.element.on("delete_node.jstree",a.proxy(function(b,c){var d=this.get_node(c.parent),e=this._model.data,f,g,h,i,j=this.settings.checkbox.tie_selection;while(d&&d.id!==a.jstree.root&&!d.state[j?"selected":"checked"]){for(h=0,f=0,g=d.children.length;g>f;f++)h+=e[d.children[f]].state[j?"selected":"checked"];if(!(g>0&&h===g))break;d.state[j?"selected":"checked"]=!0,this._data[j?"core":"checkbox"].selected.push(d.id),i=this.get_node(d,!0),i&&i.length&&i.attr("aria-selected",!0).children(".jstree-anchor").addClass(j?"jstree-clicked":"jstree-checked"),d=this.get_node(d.parent)}},this)).on("move_node.jstree",a.proxy(function(b,c){var d=c.is_multi,e=c.old_parent,f=this.get_node(c.parent),g=this._model.data,h,i,j,k,l,m=this.settings.checkbox.tie_selection;if(!d){h=this.get_node(e);while(h&&h.id!==a.jstree.root&&!h.state[m?"selected":"checked"]){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(!(k>0&&i===k))break;h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),h=this.get_node(h.parent)}}h=f;while(h&&h.id!==a.jstree.root){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(i===k)h.state[m?"selected":"checked"]||(h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"));else{if(!h.state[m?"selected":"checked"])break;h.state[m?"selected":"checked"]=!1,this._data[m?"core":"checkbox"].selected=a.vakata.array_remove_item(this._data[m?"core":"checkbox"].selected,h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!1).children(".jstree-anchor").removeClass(m?"jstree-clicked":"jstree-checked")}h=this.get_node(h.parent)}},this))},this.get_undetermined=function(c){if(-1===this.settings.checkbox.cascade.indexOf("undetermined"))return[];var d,e,f,g,h={},i=this._model.data,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l=[],m=this,n=[];for(d=0,e=k.length;e>d;d++)if(i[k[d]]&&i[k[d]].parents)for(f=0,g=i[k[d]].parents.length;g>f;f++){if(h[i[k[d]].parents[f]]!==b)break;i[k[d]].parents[f]!==a.jstree.root&&(h[i[k[d]].parents[f]]=!0,l.push(i[k[d]].parents[f]))}for(this.element.find(".jstree-closed").not(":has(.jstree-children)").each(function(){var c=m.get_node(this),j;if(c)if(c.state.loaded){for(d=0,e=c.children_d.length;e>d;d++)if(j=i[c.children_d[d]],!j.state.loaded&&j.original&&j.original.state&&j.original.state.undetermined&&j.original.state.undetermined===!0)for(h[j.id]===b&&j.id!==a.jstree.root&&(h[j.id]=!0,l.push(j.id)),f=0,g=j.parents.length;g>f;f++)h[j.parents[f]]===b&&j.parents[f]!==a.jstree.root&&(h[j.parents[f]]=!0,l.push(j.parents[f]))}else if(c.original&&c.original.state&&c.original.state.undetermined&&c.original.state.undetermined===!0)for(h[c.id]===b&&c.id!==a.jstree.root&&(h[c.id]=!0,l.push(c.id)),f=0,g=c.parents.length;g>f;f++)h[c.parents[f]]===b&&c.parents[f]!==a.jstree.root&&(h[c.parents[f]]=!0,l.push(c.parents[f]))}),d=0,e=l.length;e>d;d++)i[l[d]].state[j?"selected":"checked"]||n.push(c?i[l[d]]:l[d]);return n},this._undetermined=function(){if(null!==this.element){var a=this.get_undetermined(!1),b,c,d;for(this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),b=0,c=a.length;c>b;b++)d=this.get_node(a[b],!0),d&&d.length&&d.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-undetermined")}},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments)){var g,h,i=null,j=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(!this.settings.checkbox.tie_selection&&this._model.data[b.id].state.checked&&(i.className+=" jstree-checked"),j=l.cloneNode(!1),this._model.data[b.id].state.checkbox_disabled&&(j.className+=" jstree-checkbox-disabled"),i.insertBefore(j,i.childNodes[0]))}return e||-1===this.settings.checkbox.cascade.indexOf("undetermined")||(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)),b},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.get_container_ul().removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.get_container_ul().addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()},this.is_undetermined=function(b){b=this.get_node(b);var c=this.settings.checkbox.cascade,d,e,f=this.settings.checkbox.tie_selection,g=this._data[f?"core":"checkbox"].selected,h=this._model.data;if(!b||b.state[f?"selected":"checked"]===!0||-1===c.indexOf("undetermined")||-1===c.indexOf("down")&&-1===c.indexOf("up"))return!1;if(!b.state.loaded&&b.original.state.undetermined===!0)return!0;for(d=0,e=b.children_d.length;e>d;d++)if(-1!==a.inArray(b.children_d[d],g)||!h[b.children_d[d]].state.loaded&&h[b.children_d[d]].original.state.undetermined)return!0;return!1},this.disable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled||(b.state.checkbox_disabled=!0,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-checkbox-disabled"),this.trigger("disable_checkbox",{node:b})))):!1},this.enable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled&&(b.state.checkbox_disabled=!1,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").removeClass("jstree-checkbox-disabled"),this.trigger("enable_checkbox",{node:b})))):!1},this.activate_node=function(b,c){return a(c.target).hasClass("jstree-checkbox-disabled")?!1:(this.settings.checkbox.tie_selection&&(this.settings.checkbox.whole_node||a(c.target).hasClass("jstree-checkbox"))&&(c.ctrlKey=!0),this.settings.checkbox.tie_selection||!this.settings.checkbox.whole_node&&!a(c.target).hasClass("jstree-checkbox")?d.activate_node.call(this,b,c):this.is_disabled(b)?!1:(this.is_checked(b)?this.uncheck_node(b,c):this.check_node(b,c),void this.trigger("activate_node",{node:this.get_node(b)})))},this._cascade_new_checked_state=function(a,b){var c=this,d=this.settings.checkbox.tie_selection,e=this._model.data[a],f=[],g=[],h,i,j;if(!this.settings.checkbox.cascade_to_disabled&&e.state.disabled||!this.settings.checkbox.cascade_to_hidden&&e.state.hidden)j=this.get_checked_descendants(a),e.state[d?"selected":"checked"]&&j.push(e.id),f=f.concat(j);else{if(e.children)for(h=0,i=e.children.length;i>h;h++){var k=e.children[h];j=c._cascade_new_checked_state(k,b),f=f.concat(j),j.indexOf(k)>-1&&g.push(k)}var l=c.get_node(e,!0),m=g.length>0&&g.lengthe;e++)this.check_node(b[e],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(d=this.get_node(b,!0),void(b.state.checked||(b.state.checked=!0,this._data.checkbox.selected.push(b.id),d&&d.length&&d.children(".jstree-anchor").addClass("jstree-checked"),this.trigger("check_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.uncheck_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.deselect_node(b,!1,c);var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.uncheck_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.checked&&(b.state.checked=!1,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,b.id),f.length&&f.children(".jstree-anchor").removeClass("jstree-checked"),this.trigger("uncheck_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.check_all=function(){if(this.settings.checkbox.tie_selection)return this.select_all();var b=this._data.checkbox.selected.concat([]),c,d;for(this._data.checkbox.selected=this._model.data[a.jstree.root].children_d.concat(),c=0,d=this._data.checkbox.selected.length;d>c;c++)this._model.data[this._data.checkbox.selected[c]]&&(this._model.data[this._data.checkbox.selected[c]].state.checked=!0);this.redraw(!0),this.trigger("check_all",{selected:this._data.checkbox.selected})},this.uncheck_all=function(){if(this.settings.checkbox.tie_selection)return this.deselect_all();var a=this._data.checkbox.selected.concat([]),b,c;for(b=0,c=this._data.checkbox.selected.length;c>b;b++)this._model.data[this._data.checkbox.selected[b]]&&(this._model.data[this._data.checkbox.selected[b]].state.checked=!1);this._data.checkbox.selected=[],this.element.find(".jstree-checked").removeClass("jstree-checked"),this.trigger("uncheck_all",{selected:this._data.checkbox.selected,node:a})},this.is_checked=function(b){return this.settings.checkbox.tie_selection?this.is_selected(b):(b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.checked:!1)},this.get_checked=function(b){return this.settings.checkbox.tie_selection?this.get_selected(b):b?a.map(this._data.checkbox.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.checkbox.selected.slice()},this.get_top_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_top_selected(b);var c=this.get_checked(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},this.get_bottom_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_bottom_selected(b);var c=this.get_checked(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},this.load_node=function(b,c){var e,f,g,h,i,j;if(!a.isArray(b)&&!this.settings.checkbox.tie_selection&&(j=this.get_node(b),j&&j.state.loaded))for(e=0,f=j.children_d.length;f>e;e++)this._model.data[j.children_d[e]].state.checked&&(i=!0,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,j.children_d[e]));return d.load_node.apply(this,arguments)},this.get_state=function(){var a=d.get_state.apply(this,arguments);return this.settings.checkbox.tie_selection?a:(a.checkbox=this._data.checkbox.selected.slice(),a)},this.set_state=function(b,c){var e=d.set_state.apply(this,arguments);if(e&&b.checkbox){if(!this.settings.checkbox.tie_selection){this.uncheck_all();var f=this;a.each(b.checkbox,function(a,b){f.check_node(b)})}return delete b.checkbox,this.set_state(b,c),!1}return e},this.refresh=function(a,b){return this.settings.checkbox.tie_selection&&(this._data.checkbox.selected=[]),d.refresh.apply(this,arguments)}},a.jstree.defaults.conditionalselect=function(){return!0},a.jstree.plugins.conditionalselect=function(a,b){this.activate_node=function(a,c){return this.settings.conditionalselect.call(this,this.get_node(a),c)?b.activate_node.call(this,a,c):void 0}},a.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(b,c){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.create_node(d,{},"last",function(a){try{c.edit(a)}catch(b){setTimeout(function(){c.edit(a)},0)}})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.edit(d)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.delete_node(c.get_selected()):c.delete_node(d)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.cut(c.get_top_selected()):c.cut(d)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.copy(c.get_top_selected()):c.copy(d)}},paste:{separator_before:!1,icon:!1,_disabled:function(b){return!a.jstree.reference(b.reference).can_paste()},separator_after:!1,label:"Paste",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.paste(d)}}}}}}},a.jstree.plugins.contextmenu=function(c,d){this.bind=function(){d.bind.call(this);var b=0,c=null,e,f;this.element.on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-contextmenu")},this)).on("contextmenu.jstree",".jstree-anchor",a.proxy(function(a,d){"input"!==a.target.tagName.toLowerCase()&&(a.preventDefault(),b=a.ctrlKey?+new Date:0,(d||c)&&(b=+new Date+1e4),c&&clearTimeout(c),this.is_loading(a.currentTarget)||this.show_contextmenu(a.currentTarget,a.pageX,a.pageY,a))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(c){this._data.contextmenu.visible&&(!b||+new Date-b>250)&&a.vakata.context.hide(),b=0},this)).on("touchstart.jstree",".jstree-anchor",function(b){b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(e=b.originalEvent.changedTouches[0].clientX,f=b.originalEvent.changedTouches[0].clientY,c=setTimeout(function(){a(b.currentTarget).trigger("contextmenu",!0)},750))}).on("touchmove.vakata.jstree",function(b){c&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(Math.abs(e-b.originalEvent.changedTouches[0].clientX)>10||Math.abs(f-b.originalEvent.changedTouches[0].clientY)>10)&&(clearTimeout(c),a.vakata.context.hide())}).on("touchend.vakata.jstree",function(a){c&&clearTimeout(c)}),a(i).on("context_hide.vakata.jstree",a.proxy(function(b,c){this._data.contextmenu.visible=!1,a(c.reference).removeClass("jstree-context")},this))},this.teardown=function(){this._data.contextmenu.visible&&a.vakata.context.hide(),d.teardown.call(this)},this.show_contextmenu=function(c,d,e,f){if(c=this.get_node(c),!c||c.id===a.jstree.root)return!1;var g=this.settings.contextmenu,h=this.get_node(c,!0),i=h.children(".jstree-anchor"),j=!1,k=!1;(g.show_at_node||d===b||e===b)&&(j=i.offset(),d=j.left,e=j.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(c)&&this.activate_node(c,f),k=g.items,a.isFunction(k)&&(k=k.call(this,c,a.proxy(function(a){this._show_contextmenu(c,d,e,a)},this))),a.isPlainObject(k)&&this._show_contextmenu(c,d,e,k)},this._show_contextmenu=function(b,c,d,e){var f=this.get_node(b,!0),g=f.children(".jstree-anchor");a(i).one("context_show.vakata.jstree",a.proxy(function(b,c){var d="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";a(c.element).addClass(d),g.addClass("jstree-context")},this)),this._data.contextmenu.visible=!0,a.vakata.context.show(g,{x:c,y:d},e),this.trigger("show_contextmenu",{node:b,x:c,y:d})}},function(a){var b=!1,c={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};a.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(b){a(i).triggerHandler("context_"+b+".vakata",{reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}})},_execute:function(b){return b=c.items[b],b&&(!b._disabled||a.isFunction(b._disabled)&&!b._disabled({ +item:b,reference:c.reference,element:c.element}))&&b.action?b.action.call(null,{item:b,reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}}):!1},_parse:function(b,d){if(!b)return!1;d||(c.html="",c.items=[]);var e="",f=!1,g;return d&&(e+=""),d||(c.html=e,a.vakata.context._trigger("parse")),e.length>10?e:!1},_show_submenu:function(c){if(c=a(c),c.length&&c.children("ul").length){var d=c.children("ul"),e=c.offset().left,f=e+c.outerWidth(),g=c.offset().top,h=d.width(),i=d.height(),j=a(window).width()+a(window).scrollLeft(),k=a(window).height()+a(window).scrollTop();b?c[f-(h+10+c.outerWidth())<0?"addClass":"removeClass"]("vakata-context-left"):c[f+h>j&&e>j-f?"addClass":"removeClass"]("vakata-context-right"),g+i+10>k&&d.css("bottom","-1px"),c.hasClass("vakata-context-right")?h>e&&d.css("margin-right",e-h):h>j-f&&d.css("margin-left",j-f-h),d.show()}},show:function(d,e,f){var g,h,j,k,l,m,n,o,p=!0;switch(c.element&&c.element.length&&c.element.width(""),p){case!e&&!d:return!1;case!!e&&!!d:c.reference=d,c.position_x=e.x,c.position_y=e.y;break;case!e&&!!d:c.reference=d,g=d.offset(),c.position_x=g.left+d.outerHeight(),c.position_y=g.top;break;case!!e&&!d:c.position_x=e.x,c.position_y=e.y}d&&!f&&a(d).data("vakata_contextmenu")&&(f=a(d).data("vakata_contextmenu")),a.vakata.context._parse(f)&&c.element.html(c.html),c.items.length&&(c.element.appendTo(i.body),h=c.element,j=c.position_x,k=c.position_y,l=h.width(),m=h.height(),n=a(window).width()+a(window).scrollLeft(),o=a(window).height()+a(window).scrollTop(),b&&(j-=h.outerWidth()-a(d).outerWidth(),jn&&(j=n-(l+20)),k+m+20>o&&(k=o-(m+20)),c.element.css({left:j,top:k}).show().find("a").first().focus().parent().addClass("vakata-context-hover"),c.is_visible=!0,a.vakata.context._trigger("show"))},hide:function(){c.is_visible&&(c.element.hide().find("ul").hide().end().find(":focus").blur().end().detach(),c.is_visible=!1,a.vakata.context._trigger("hide"))}},a(function(){b="rtl"===a(i.body).css("direction");var d=!1;c.element=a("
      "),c.element.on("mouseenter","li",function(b){b.stopImmediatePropagation(),a.contains(this,b.relatedTarget)||(d&&clearTimeout(d),c.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),a(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),a.vakata.context._show_submenu(this))}).on("mouseleave","li",function(b){a.contains(this,b.relatedTarget)||a(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(b){a(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),a.vakata.context.settings.hide_onmouseleave&&(d=setTimeout(function(b){return function(){a.vakata.context.hide()}}(this),a.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(b){b.preventDefault(),a(this).blur().parent().hasClass("vakata-context-disabled")||a.vakata.context._execute(a(this).attr("rel"))===!1||a.vakata.context.hide()}).on("keydown","a",function(b){var d=null;switch(b.which){case 13:case 32:b.type="click",b.preventDefault(),a(b.currentTarget).trigger(b);break;case 37:c.is_visible&&(c.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 38:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 39:c.is_visible&&(c.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 40:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 27:a.vakata.context.hide(),b.preventDefault()}}).on("keydown",function(a){a.preventDefault();var b=c.element.find(".vakata-contextmenu-shortcut-"+a.which).parent();b.parent().not(".vakata-context-disabled")&&b.click()}),a(i).on("mousedown.vakata.jstree",function(b){c.is_visible&&c.element[0]!==b.target&&!a.contains(c.element[0],b.target)&&a.vakata.context.hide()}).on("context_show.vakata.jstree",function(a,d){c.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),b&&c.element.addClass("vakata-context-rtl").css("direction","rtl"),c.element.find("ul").hide().end()})})}(a),a.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1};var m,n;a.jstree.plugins.dnd=function(b,c){this.init=function(a,b){c.init.call(this,a,b),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in i.createElement("span")},this.bind=function(){c.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",a.proxy(function(b){if(this.settings.dnd.large_drag_target&&a(b.target).closest(".jstree-node")[0]!==b.currentTarget)return!0;if("touchstart"===b.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var c=this.get_node(b.target),d=this.is_selected(c)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,e=d>1?d+" "+this.get_string("nodes"):this.get_text(b.currentTarget);if(this.settings.core.force_text&&(e=a.vakata.html.escape(e)),c&&c.id&&c.id!==a.jstree.root&&(1===b.which||"touchstart"===b.type||"dragstart"===b.type)&&(this.settings.dnd.is_draggable===!0||a.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,d>1?this.get_top_selected(!0):[c],b))){if(m={jstree:!0,origin:this,obj:this.get_node(c,!0),nodes:d>1?this.get_top_selected():[c.id]},n=b.currentTarget,!this.settings.dnd.use_html5)return this.element.trigger("mousedown.jstree"),a.vakata.dnd.start(b,m,'
      '+e+'
      ');a.vakata.dnd._trigger("start",b,{helper:a(),element:n,data:m})}},this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(b){return b.preventDefault(),a.vakata.dnd._trigger("move",b,{helper:a(),element:n,data:m}),!1}).on("drop.jstree",a.proxy(function(b){return b.preventDefault(),a.vakata.dnd._trigger("stop",b,{helper:a(),element:n,data:m}),!1},this))},this.redraw_node=function(a,b,d,e){if(a=c.redraw_node.apply(this,arguments),a&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)a.setAttribute("draggable",!0);else{var f,g,h=null;for(f=0,g=a.childNodes.length;g>f;f++)if(a.childNodes[f]&&a.childNodes[f].className&&-1!==a.childNodes[f].className.indexOf("jstree-anchor")){h=a.childNodes[f];break}h&&h.setAttribute("draggable",!0)}return a}},a(function(){var c=!1,d=!1,e=!1,f=!1,g=a('
       
      ').hide();a(i).on("dragover.vakata.jstree",function(b){n&&a.vakata.dnd._trigger("move",b,{helper:a(),element:n,data:m})}).on("drop.vakata.jstree",function(b){n&&(a.vakata.dnd._trigger("stop",b,{helper:a(),element:n,data:m}),n=null,m=null)}).on("dnd_start.vakata.jstree",function(a,b){c=!1,e=!1,b&&b.data&&b.data.jstree&&g.appendTo(i.body)}).on("dnd_move.vakata.jstree",function(h,i){var j=i.event.target!==e.target;if(f&&(!i.event||"dragover"!==i.event.type||j)&&clearTimeout(f),i&&i.data&&i.data.jstree&&(!i.event.target.id||"jstree-marker"!==i.event.target.id)){e=i.event;var k=a.jstree.reference(i.event.target),l=!1,m=!1,n=!1,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F;if(k&&k._data&&k._data.dnd)if(g.attr("class","jstree-"+k.get_theme()+(k.settings.core.themes.responsive?" jstree-dnd-responsive":"")),D=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey)),i.helper.children().attr("class","jstree-"+k.get_theme()+" jstree-"+k.get_theme()+"-"+k.get_theme_variant()+" "+(k.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[D?"show":"hide"](),i.event.target!==k.element[0]&&i.event.target!==k.get_container_ul()[0]||0!==k.get_container_ul().children().length){if(l=k.settings.dnd.large_drop_target?a(i.event.target).closest(".jstree-node").children(".jstree-anchor"):a(i.event.target).closest(".jstree-anchor"),l&&l.length&&l.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(m=l.offset(),n=(i.event.pageY!==b?i.event.pageY:i.event.originalEvent.pageY)-m.top,r=l.outerHeight(),u=r/3>n?["b","i","a"]:n>r-r/3?["a","i","b"]:n>r/2?["i","a","b"]:["i","b","a"],a.each(u,function(b,e){switch(e){case"b":p=m.left-6,q=m.top,s=k.get_parent(l),t=l.parent().index(),F="jstree-below";break;case"i":B=k.settings.dnd.inside_pos,C=k.get_node(l.parent()),p=m.left-2,q=m.top+r/2+1,s=C.id,t="first"===B?0:"last"===B?C.children.length:Math.min(B,C.children.length),F="jstree-inside";break;case"a":p=m.left-6,q=m.top+r,s=k.get_parent(l),t=l.parent().index()+1,F="jstree-above"}for(v=!0,w=0,x=i.data.nodes.length;x>w;w++)if(y=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",z=t,"move_node"===y&&"a"===e&&i.data.origin&&i.data.origin===k&&s===k.get_parent(i.data.nodes[w])&&(A=k.get_node(s),z>a.inArray(i.data.nodes[w],A.children)&&(z-=1)),v=v&&(k&&k.settings&&k.settings.dnd&&k.settings.dnd.check_while_dragging===!1||k.check(y,i.data.origin&&i.data.origin!==k?i.data.origin.get_node(i.data.nodes[w]):i.data.nodes[w],s,z,{dnd:!0,ref:k.get_node(l.parent()),pos:e,origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==k,is_foreign:!i.data.origin})),!v){k&&k.last_error&&(d=k.last_error());break}return"i"===e&&l.parent().is(".jstree-closed")&&k.settings.dnd.open_timeout&&(!i.event||"dragover"!==i.event.type||j)&&(f&&clearTimeout(f),f=setTimeout(function(a,b){return function(){a.open_node(b)}}(k,l),k.settings.dnd.open_timeout)),v?(E=k.get_node(s,!0),E.hasClass(".jstree-dnd-parent")||(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),E.addClass("jstree-dnd-parent")),c={ins:k,par:s,pos:"i"!==e||"last"!==B||0!==t||k.is_loaded(C)?t:"last"},g.css({left:p+"px",top:q+"px"}).show(),g.removeClass("jstree-above jstree-inside jstree-below").addClass(F),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=D?"copy":"move"),d={},u=!0,!1):void 0}),u===!0))return}else{for(v=!0,w=0,x=i.data.nodes.length;x>w;w++)if(v=v&&k.check(i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",i.data.origin&&i.data.origin!==k?i.data.origin.get_node(i.data.nodes[w]):i.data.nodes[w],a.jstree.root,"last",{dnd:!0,ref:k.get_node(a.jstree.root),pos:"i",origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==k,is_foreign:!i.data.origin}),!v)break;if(v)return c={ins:k,par:a.jstree.root,pos:"last"},g.hide(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),void(i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=D?"copy":"move"))}a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),c=!1,i.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),i.event.originalEvent&&i.event.originalEvent.dataTransfer,g.hide()}}).on("dnd_scroll.vakata.jstree",function(a,b){b&&b.data&&b.data.jstree&&(g.hide(),c=!1,e=!1,b.helper.find(".jstree-icon").first().removeClass("jstree-ok").addClass("jstree-er"))}).on("dnd_stop.vakata.jstree",function(b,h){if(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),f&&clearTimeout(f),h&&h.data&&h.data.jstree){g.hide().detach();var i,j,k=[];if(c){for(i=0,j=h.data.nodes.length;j>i;i++)k[i]=h.data.origin?h.data.origin.get_node(h.data.nodes[i]):h.data.nodes[i];c.ins[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(h.event.metaKey||h.event.ctrlKey))?"copy_node":"move_node"](k,c.par,c.pos,!1,!1,!1,h.data.origin)}else i=a(h.event.target).closest(".jstree"),i.length&&d&&d.error&&"check"===d.error&&(i=i.jstree(!0),i&&i.settings.core.error.call(this,d));e=!1,c=!1}}).on("keyup.jstree keydown.jstree",function(b,h){h=a.vakata.dnd._get(),h&&h.data&&h.data.jstree&&("keyup"===b.type&&27===b.which?(f&&clearTimeout(f),c=!1,d=!1,e=!1,f=!1,g.hide().detach(),a.vakata.dnd._clean()):(h.helper.find(".jstree-copy").first()[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(b.metaKey||b.ctrlKey))?"show":"hide"](),e&&(e.metaKey=b.metaKey,e.ctrlKey=b.ctrlKey,a.vakata.dnd._trigger("move",e))))})}),function(a){a.vakata.html={div:a("
      "),escape:function(b){return a.vakata.html.div.text(b).html()},strip:function(b){return a.vakata.html.div.empty().append(a.parseHTML(b)).text()}};var c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1};a.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:10},_trigger:function(c,d,e){e===b&&(e=a.vakata.dnd._get()),e.event=d,a(i).triggerHandler("dnd_"+c+".vakata",e)},_get:function(){return{data:c.data,element:c.element,helper:c.helper}},_clean:function(){c.helper&&c.helper.remove(),c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},n=null,a(i).off("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).off("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop)},_scroll:function(b){if(!c.scroll_e||!c.scroll_l&&!c.scroll_t)return c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),!1;if(!c.scroll_i)return c.scroll_i=setInterval(a.vakata.dnd._scroll,100),!1;if(b===!0)return!1;var d=c.scroll_e.scrollTop(),e=c.scroll_e.scrollLeft();c.scroll_e.scrollTop(d+c.scroll_t*a.vakata.dnd.settings.scroll_speed),c.scroll_e.scrollLeft(e+c.scroll_l*a.vakata.dnd.settings.scroll_speed),(d!==c.scroll_e.scrollTop()||e!==c.scroll_e.scrollLeft())&&a.vakata.dnd._trigger("scroll",c.scroll_e)},start:function(b,d,e){"touchstart"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag&&a.vakata.dnd.stop({});try{b.currentTarget.unselectable="on",b.currentTarget.onselectstart=function(){return!1},b.currentTarget.style&&(b.currentTarget.style.touchAction="none",b.currentTarget.style.msTouchAction="none",b.currentTarget.style.MozUserSelect="none")}catch(f){}return c.init_x=b.pageX,c.init_y=b.pageY,c.data=d,c.is_down=!0,c.element=b.currentTarget,c.target=b.target,c.is_touch="touchstart"===b.type,e!==!1&&(c.helper=a("
      ").html(e).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),a(i).on("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).on("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop),!1},drag:function(b){if("touchmove"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_down){if(!c.is_drag){if(!(Math.abs(b.pageX-c.init_x)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)||Math.abs(b.pageY-c.init_y)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)))return;c.helper&&(c.helper.appendTo(i.body),c.helper_w=c.helper.outerWidth()),c.is_drag=!0,a(c.target).one("click.vakata",!1),a.vakata.dnd._trigger("start",b)}var d=!1,e=!1,f=!1,g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n=!1;return c.scroll_t=0,c.scroll_l=0,c.scroll_e=!1,a(a(b.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return/^auto|scroll$/.test(a(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var d=a(this),e=d.offset();return this.scrollHeight>this.offsetHeight&&(e.top+d.height()-b.pageYthis.offsetWidth&&(e.left+d.width()-b.pageXg&&b.pageY-kg&&g-(b.pageY-k)j&&b.pageX-lj&&j-(b.pageX-l)f&&(m=f-50),h&&n+c.helper_w>h&&(n=h-(c.helper_w+2)),c.helper.css({left:n+"px",top:m+"px"})),a.vakata.dnd._trigger("move",b),!1}},stop:function(b){if("touchend"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag)b.target!==c.target&&a(c.target).off("click.vakata"),a.vakata.dnd._trigger("stop",b);else if("touchend"===b.type&&b.target===c.target){var d=setTimeout(function(){a(b.target).click()},100);a(b.target).one("click",function(){d&&clearTimeout(d)})}return a.vakata.dnd._clean(),!1}}}(a),a.jstree.defaults.massload=null,a.jstree.plugins.massload=function(b,c){this.init=function(a,b){this._data.massload={},c.init.call(this,a,b)},this._load_nodes=function(b,d,e,f){var g=this.settings.massload,h=[],i=this._model.data,j,k,l;if(!e){for(j=0,k=b.length;k>j;j++)(!i[b[j]]||!i[b[j]].state.loaded&&!i[b[j]].state.failed||f)&&(h.push(b[j]),l=this.get_node(b[j],!0),l&&l.length&&l.addClass("jstree-loading").attr("aria-busy",!0));if(this._data.massload={},h.length){if(a.isFunction(g))return g.call(this,h,a.proxy(function(a){var g,h;if(a)for(g in a)a.hasOwnProperty(g)&&(this._data.massload[g]=a[g]);for(g=0,h=b.length;h>g;g++)l=this.get_node(b[g],!0),l&&l.length&&l.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this));if("object"==typeof g&&g&&g.url)return g=a.extend(!0,{},g),a.isFunction(g.url)&&(g.url=g.url.call(this,h)),a.isFunction(g.data)&&(g.data=g.data.call(this,h)),a.ajax(g).done(a.proxy(function(a,g,h){var i,j;if(a)for(i in a)a.hasOwnProperty(i)&&(this._data.massload[i]=a[i]);for(i=0,j=b.length;j>i;i++)l=this.get_node(b[i],!0),l&&l.length&&l.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this)).fail(a.proxy(function(a){c._load_nodes.call(this,b,d,e,f)},this))}}return c._load_nodes.call(this,b,d,e,f)},this._load_node=function(b,d){var e=this._data.massload[b.id],f=null,g;return e?(f=this["string"==typeof e?"_append_html_data":"_append_json_data"](b,"string"==typeof e?a(a.parseHTML(e)).filter(function(){return 3!==this.nodeType}):e,function(a){d.call(this,a)}),g=this.get_node(b.id,!0),g&&g.length&&g.removeClass("jstree-loading").attr("aria-busy",!1),delete this._data.massload[b.id],f):c._load_node.call(this,b,d)}},a.jstree.defaults.search={ajax:!1,fuzzy:!1,case_sensitive:!1,show_only_matches:!1,show_only_matches_children:!1,close_opened_onclear:!0,search_leaves_only:!1,search_callback:!1},a.jstree.plugins.search=function(c,d){this.bind=function(){d.bind.call(this),this._data.search.str="",this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=!1,this._data.search.smc=!1,this._data.search.hdn=[],this.element.on("search.jstree",a.proxy(function(b,c){if(this._data.search.som&&c.res.length){var d=this._model.data,e,f,g=[],h,i;for(e=0,f=c.res.length;f>e;e++)if(d[c.res[e]]&&!d[c.res[e]].state.hidden&&(g.push(c.res[e]),g=g.concat(d[c.res[e]].parents),this._data.search.smc))for(h=0,i=d[c.res[e]].children_d.length;i>h;h++)d[d[c.res[e]].children_d[h]]&&!d[d[c.res[e]].children_d[h]].state.hidden&&g.push(d[c.res[e]].children_d[h]);g=a.vakata.array_remove_item(a.vakata.array_unique(g),a.jstree.root),this._data.search.hdn=this.hide_all(!0),this.show_node(g,!0),this.redraw(!0)}},this)).on("clear_search.jstree",a.proxy(function(a,b){this._data.search.som&&b.res.length&&(this.show_node(this._data.search.hdn,!0),this.redraw(!0))},this))},this.search=function(c,d,e,f,g,h){if(c===!1||""===a.trim(c.toString()))return this.clear_search();f=this.get_node(f),f=f&&f.id?f.id:null,c=c.toString();var i=this.settings.search,j=i.ajax?i.ajax:!1,k=this._model.data,l=null,m=[],n=[],o,p;if(this._data.search.res.length&&!g&&this.clear_search(),e===b&&(e=i.show_only_matches),h===b&&(h=i.show_only_matches_children),!d&&j!==!1)return a.isFunction(j)?j.call(this,c,a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this),f):(j=a.extend({},j),j.data||(j.data={}),j.data.str=c,f&&(j.data.inside=f),this._data.search.lastRequest&&this._data.search.lastRequest.abort(),this._data.search.lastRequest=a.ajax(j).fail(a.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(j)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this)),this._data.search.lastRequest);if(g||(this._data.search.str=c,this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=e,this._data.search.smc=h),l=new a.vakata.search(c,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),a.each(k[f?f:a.jstree.root].children_d,function(a,b){var d=k[b];d.text&&!d.state.hidden&&(!i.search_leaves_only||d.state.loaded&&0===d.children.length)&&(i.search_callback&&i.search_callback.call(this,c,d)||!i.search_callback&&l.search(d.text).isMatch)&&(m.push(b),n=n.concat(d.parents))}),m.length){for(n=a.vakata.array_unique(n),o=0,p=n.length;p>o;o++)n[o]!==a.jstree.root&&k[n[o]]&&this.open_node(n[o],null,0)===!0&&this._data.search.opn.push(n[o]);g?(this._data.search.dom=this._data.search.dom.add(a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #")))),this._data.search.res=a.vakata.array_unique(this._data.search.res.concat(m))):(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.res=m),this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:c,res:this._data.search.res,show_only_matches:e})},this.clear_search=function(){this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.res.length&&(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(this._data.search.res,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search")),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=a()},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments),b&&-1!==a.inArray(b.id,this._data.search.res)){var g,h,i=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(i.className+=" jstree-search")}return b}},function(a){a.vakata.search=function(b,c,d){d=d||{},d=a.extend({},a.vakata.search.defaults,d),d.fuzzy!==!1&&(d.fuzzy=!0),b=d.caseSensitive?b:b.toLowerCase();var e=d.location,f=d.distance,g=d.threshold,h=b.length,i,j,k,l;return h>32&&(d.fuzzy=!1),d.fuzzy&&(i=1<c;c++)a[b.charAt(c)]=0;for(c=0;h>c;c++)a[b.charAt(c)]|=1<c;c++){o=0,p=q;while(p>o)k(c,e+p)<=m?o=p:q=p,p=Math.floor((q-o)/2+o);for(q=p,s=Math.max(1,e-p+1),t=Math.min(e+p,l)+h,u=new Array(t+2),u[t+1]=(1<=s;f--)if(v=j[a.charAt(f-1)],0===c?u[f]=(u[f+1]<<1|1)&v:u[f]=(u[f+1]<<1|1)&v|((r[f+1]|r[f])<<1|1)|r[f+1],u[f]&i&&(w=k(c,f-1),m>=w)){if(m=w,n=f-1,x.push(n),!(n>e))break;s=Math.max(1,2*e-n)}if(k(c+1,e)>m)break;r=u}return{isMatch:n>=0,score:w}},c===!0?{search:l}:l(c)},a.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1}}(a),a.jstree.defaults.sort=function(a,b){return this.get_text(a)>this.get_text(b)?1:-1},a.jstree.plugins.sort=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("model.jstree",a.proxy(function(a,b){this.sort(b.parent,!0)},this)).on("rename_node.jstree create_node.jstree",a.proxy(function(a,b){this.sort(b.parent||b.node.parent,!1),this.redraw_node(b.parent||b.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",a.proxy(function(a,b){this.sort(b.parent,!1),this.redraw_node(b.parent,!0)},this))},this.sort=function(b,c){var d,e;if(b=this.get_node(b),b&&b.children&&b.children.length&&(b.children.sort(a.proxy(this.settings.sort,this)),c))for(d=0,e=b.children_d.length;e>d;d++)this.sort(b.children_d[d],!1)}};var o=!1;a.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree",ttl:!1,filter:!1,preserve_loaded:!1},a.jstree.plugins.state=function(b,c){this.bind=function(){c.bind.call(this);var b=a.proxy(function(){this.element.on(this.settings.state.events,a.proxy(function(){o&&clearTimeout(o),o=setTimeout(a.proxy(function(){this.save_state()},this),100)},this)),this.trigger("state_ready")},this);this.element.on("ready.jstree",a.proxy(function(a,c){this.element.one("restore_state.jstree",b),this.restore_state()||b()},this))},this.save_state=function(){var b=this.get_state();this.settings.state.preserve_loaded||delete b.core.loaded;var c={state:b,ttl:this.settings.state.ttl,sec:+new Date};a.vakata.storage.set(this.settings.state.key,JSON.stringify(c))},this.restore_state=function(){var b=a.vakata.storage.get(this.settings.state.key);if(b)try{b=JSON.parse(b)}catch(c){return!1}return b&&b.ttl&&b.sec&&+new Date-b.sec>b.ttl?!1:(b&&b.state&&(b=b.state),b&&a.isFunction(this.settings.state.filter)&&(b=this.settings.state.filter.call(this,b)),b?(this.settings.state.preserve_loaded||delete b.core.loaded,this.element.one("set_state.jstree",function(c,d){d.instance.trigger("restore_state",{state:a.extend(!0,{},b)})}),this.set_state(b),!0):!1)},this.clear_state=function(){return a.vakata.storage.del(this.settings.state.key)}},function(a,b){a.vakata.storage={set:function(a,b){return window.localStorage.setItem(a,b)},get:function(a){return window.localStorage.getItem(a)},del:function(a){return window.localStorage.removeItem(a)}}}(a),a.jstree.defaults.types={"default":{}},a.jstree.defaults.types[a.jstree.root]={},a.jstree.plugins.types=function(c,d){this.init=function(c,e){var f,g;if(e&&e.types&&e.types["default"])for(f in e.types)if("default"!==f&&f!==a.jstree.root&&e.types.hasOwnProperty(f))for(g in e.types["default"])e.types["default"].hasOwnProperty(g)&&e.types[f][g]===b&&(e.types[f][g]=e.types["default"][g]);d.init.call(this,c,e),this._model.data[a.jstree.root].type=a.jstree.root},this.refresh=function(b,c){d.refresh.call(this,b,c),this._model.data[a.jstree.root].type=a.jstree.root},this.bind=function(){this.element.on("model.jstree",a.proxy(function(c,d){var e=this._model.data,f=d.nodes,g=this.settings.types,h,i,j="default",k;for(h=0,i=f.length;i>h;h++){if(j="default",e[f[h]].original&&e[f[h]].original.type&&g[e[f[h]].original.type]&&(j=e[f[h]].original.type),e[f[h]].data&&e[f[h]].data.jstree&&e[f[h]].data.jstree.type&&g[e[f[h]].data.jstree.type]&&(j=e[f[h]].data.jstree.type), +e[f[h]].type=j,e[f[h]].icon===!0&&g[j].icon!==b&&(e[f[h]].icon=g[j].icon),g[j].li_attr!==b&&"object"==typeof g[j].li_attr)for(k in g[j].li_attr)if(g[j].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].li_attr[k]===b?e[f[h]].li_attr[k]=g[j].li_attr[k]:"class"===k&&(e[f[h]].li_attr["class"]=g[j].li_attr["class"]+" "+e[f[h]].li_attr["class"])}if(g[j].a_attr!==b&&"object"==typeof g[j].a_attr)for(k in g[j].a_attr)if(g[j].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].a_attr[k]===b?e[f[h]].a_attr[k]=g[j].a_attr[k]:"href"===k&&"#"===e[f[h]].a_attr[k]?e[f[h]].a_attr.href=g[j].a_attr.href:"class"===k&&(e[f[h]].a_attr["class"]=g[j].a_attr["class"]+" "+e[f[h]].a_attr["class"])}}e[a.jstree.root].type=a.jstree.root},this)),d.bind.call(this)},this.get_json=function(b,c,e){var f,g,h=this._model.data,i=c?a.extend(!0,{},c,{no_id:!1}):{},j=d.get_json.call(this,b,i,e);if(j===!1)return!1;if(a.isArray(j))for(f=0,g=j.length;g>f;f++)j[f].type=j[f].id&&h[j[f].id]&&h[j[f].id].type?h[j[f].id].type:"default",c&&c.no_id&&(delete j[f].id,j[f].li_attr&&j[f].li_attr.id&&delete j[f].li_attr.id,j[f].a_attr&&j[f].a_attr.id&&delete j[f].a_attr.id);else j.type=j.id&&h[j.id]&&h[j.id].type?h[j.id].type:"default",c&&c.no_id&&(j=this._delete_ids(j));return j},this._delete_ids=function(b){if(a.isArray(b)){for(var c=0,d=b.length;d>c;c++)b[c]=this._delete_ids(b[c]);return b}return delete b.id,b.li_attr&&b.li_attr.id&&delete b.li_attr.id,b.a_attr&&b.a_attr.id&&delete b.a_attr.id,b.children&&a.isArray(b.children)&&(b.children=this._delete_ids(b.children)),b},this.check=function(c,e,f,g,h){if(d.check.call(this,c,e,f,g,h)===!1)return!1;e=e&&e.id?e:this.get_node(e),f=f&&f.id?f:this.get_node(f);var i=e&&e.id?h&&h.origin?h.origin:a.jstree.reference(e.id):null,j,k,l,m;switch(i=i&&i._model&&i._model.data?i._model.data:null,c){case"create_node":case"move_node":case"copy_node":if("move_node"!==c||-1===a.inArray(e.id,f.children)){if(j=this.get_rules(f),j.max_children!==b&&-1!==j.max_children&&j.max_children===f.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(j.valid_children!==b&&-1!==j.valid_children&&-1===a.inArray(e.type||"default",j.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(i&&e.children_d&&e.parents){for(k=0,l=0,m=e.children_d.length;m>l;l++)k=Math.max(k,i[e.children_d[l]].parents.length);k=k-e.parents.length+1}(0>=k||k===b)&&(k=1);do{if(j.max_depth!==b&&-1!==j.max_depth&&j.max_depthg;g++)this.set_type(c[g],d);return!0}if(f=this.settings.types,c=this.get_node(c),!f[d]||!c)return!1;if(l=this.get_node(c,!0),l&&l.length&&(m=l.children(".jstree-anchor")),i=c.type,j=this.get_icon(c),c.type=d,(j===!0||!f[i]||f[i].icon!==b&&j===f[i].icon)&&this.set_icon(c,f[d].icon!==b?f[d].icon:!0),f[i]&&f[i].li_attr!==b&&"object"==typeof f[i].li_attr)for(k in f[i].li_attr)if(f[i].li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].li_attr["class"]=(e[c.id].li_attr["class"]||"").replace(f[i].li_attr[k],""),l&&l.removeClass(f[i].li_attr[k])):e[c.id].li_attr[k]===f[i].li_attr[k]&&(e[c.id].li_attr[k]=null,l&&l.removeAttr(k))}if(f[i]&&f[i].a_attr!==b&&"object"==typeof f[i].a_attr)for(k in f[i].a_attr)if(f[i].a_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].a_attr["class"]=(e[c.id].a_attr["class"]||"").replace(f[i].a_attr[k],""),m&&m.removeClass(f[i].a_attr[k])):e[c.id].a_attr[k]===f[i].a_attr[k]&&("href"===k?(e[c.id].a_attr[k]="#",m&&m.attr("href","#")):(delete e[c.id].a_attr[k],m&&m.removeAttr(k)))}if(f[d].li_attr!==b&&"object"==typeof f[d].li_attr)for(k in f[d].li_attr)if(f[d].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].li_attr[k]===b?(e[c.id].li_attr[k]=f[d].li_attr[k],l&&("class"===k?l.addClass(f[d].li_attr[k]):l.attr(k,f[d].li_attr[k]))):"class"===k&&(e[c.id].li_attr["class"]=f[d].li_attr[k]+" "+e[c.id].li_attr["class"],l&&l.addClass(f[d].li_attr[k]))}if(f[d].a_attr!==b&&"object"==typeof f[d].a_attr)for(k in f[d].a_attr)if(f[d].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].a_attr[k]===b?(e[c.id].a_attr[k]=f[d].a_attr[k],m&&("class"===k?m.addClass(f[d].a_attr[k]):m.attr(k,f[d].a_attr[k]))):"href"===k&&"#"===e[c.id].a_attr[k]?(e[c.id].a_attr.href=f[d].a_attr.href,m&&m.attr("href",f[d].a_attr.href)):"class"===k&&(e[c.id].a_attr["class"]=f[d].a_attr["class"]+" "+e[c.id].a_attr["class"],m&&m.addClass(f[d].a_attr[k]))}return!0}},a.jstree.defaults.unique={case_sensitive:!1,trim_whitespace:!1,duplicate:function(a,b){return a+" ("+b+")"}},a.jstree.plugins.unique=function(c,d){this.check=function(b,c,e,f,g){if(d.check.call(this,b,c,e,f,g)===!1)return!1;if(c=c&&c.id?c:this.get_node(c),e=e&&e.id?e:this.get_node(e),!e||!e.children)return!0;var h="rename_node"===b?f:c.text,i=[],j=this.settings.unique.case_sensitive,k=this.settings.unique.trim_whitespace,l=this._model.data,m,n,o;for(m=0,n=e.children.length;n>m;m++)o=l[e.children[m]].text,j||(o=o.toLowerCase()),k&&(o=o.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),i.push(o);switch(j||(h=h.toLowerCase()),k&&(h=h.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),b){case"delete_node":return!0;case"rename_node":return o=c.text||"",j||(o=o.toLowerCase()),k&&(o=o.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),m=-1===a.inArray(h,i)||c.text&&o===h,m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"create_node":return m=-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_04",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"copy_node":return m=-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_02",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"move_node":return m=c.parent===e.id&&(!g||!g.is_multi)||-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_03",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m}return!0},this.create_node=function(c,e,f,g,h){if(!e||e.text===b){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return d.create_node.call(this,c,e,f,g,h);if(f=f===b?"last":f,!f.toString().match(/^(before|after)$/)&&!h&&!this.is_loaded(c))return d.create_node.call(this,c,e,f,g,h);e||(e={});var i,j,k,l,m,n=this._model.data,o=this.settings.unique.case_sensitive,p=this.settings.unique.trim_whitespace,q=this.settings.unique.duplicate,r;for(j=i=this.get_string("New node"),k=[],l=0,m=c.children.length;m>l;l++)r=n[c.children[l]].text,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),k.push(r);l=1,r=j,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""));while(-1!==a.inArray(r,k))j=q.call(this,i,++l).toString(),r=j,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""));e.text=j}return d.create_node.call(this,c,e,f,g,h)}};var p=i.createElement("DIV");if(p.setAttribute("unselectable","on"),p.setAttribute("role","presentation"),p.className="jstree-wholerow",p.innerHTML=" ",a.jstree.plugins.wholerow=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("ready.jstree set_state.jstree",a.proxy(function(){this.hide_dots()},this)).on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var c=!1,d,e;for(d=0,e=b.selected.length;e>d;d++)c=this.get_node(b.selected[d],!0),c&&c.length&&c.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",a.proxy(function(a,b){this.get_node(b.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",a.proxy(function(a,b){"hover_node"===a.type&&this.is_disabled(b.node)||this.get_node(b.node,!0).children(".jstree-wholerow")["hover_node"===a.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",a.proxy(function(b){if(this._data.contextmenu){b.preventDefault();var c=a.Event("contextmenu",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey,pageX:b.pageX,pageY:b.pageY});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c)}},this)).on("click.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("dblclick.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("dblclick",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",a.proxy(function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",a.proxy(function(a){return a.stopImmediatePropagation(),this.is_disabled(a.currentTarget)||this.hover_node(a.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),c.teardown.call(this)},this.redraw_node=function(b,d,e,f){if(b=c.redraw_node.apply(this,arguments)){var g=p.cloneNode(!0);-1!==a.inArray(b.id,this._data.core.selected)&&(g.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===b.id&&(g.className+=" jstree-wholerow-hovered"),b.insertBefore(g,b.childNodes[0])}return b}},window.customElements&&Object&&Object.create){var q=Object.create(HTMLElement.prototype);q.createdCallback=function(){var b={core:{},plugins:[]},c;for(c in a.jstree.plugins)a.jstree.plugins.hasOwnProperty(c)&&this.attributes[c]&&(b.plugins.push(c),this.getAttribute(c)&&JSON.parse(this.getAttribute(c))&&(b[c]=JSON.parse(this.getAttribute(c))));for(c in a.jstree.defaults.core)a.jstree.defaults.core.hasOwnProperty(c)&&this.attributes[c]&&(b.core[c]=JSON.parse(this.getAttribute(c))||this.getAttribute(c));a(this).jstree(b)};try{window.customElements.define("vakata-jstree",function(){},{prototype:q})}catch(r){}}}}); \ No newline at end of file diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/32px.png b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/32px.png new file mode 100644 index 00000000..60395729 Binary files /dev/null and b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/32px.png differ diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/40px.png b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/40px.png new file mode 100644 index 00000000..aae89ad3 Binary files /dev/null and b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/40px.png differ diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/style.css b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/style.css new file mode 100644 index 00000000..d8dc188f --- /dev/null +++ b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/style.css @@ -0,0 +1,1146 @@ +/* jsTree default dark theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.jstree-contextmenu .jstree-anchor { + -webkit-user-select: none; + /* disable selection/Copy of UIWebView */ + -webkit-touch-callout: none; + /* disable the IOS popup when long-press on a link */ +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context .vakata-contextmenu-disabled > a > i { + filter: grayscale(100%); +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default-dark .jstree-anchor, +.jstree-default-dark .jstree-animated, +.jstree-default-dark .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default-dark .jstree-hovered { + background: #555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555; +} +.jstree-default-dark .jstree-context { + background: #555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555; +} +.jstree-default-dark .jstree-clicked { + background: #5fa2db; + border-radius: 2px; + box-shadow: inset 0 0 1px #666666; +} +.jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default-dark .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #333333; +} +.jstree-default-dark .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark .jstree-search { + font-style: italic; + color: #ffffff; + font-weight: bold; +} +.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #555; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #555; +} +.jstree-default-dark > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, +.jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default-dark .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default-dark .jstree-wholerow-hovered { + background: #555; +} +.jstree-default-dark .jstree-wholerow-clicked { + background: #5fa2db; + background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); + background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); +} +.jstree-default-dark .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default-dark .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default-dark .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default-dark .jstree-wholerow { + height: 24px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default-dark .jstree-last { + background: transparent; +} +.jstree-default-dark .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default-dark .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default-dark .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default-dark .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-node, +.jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default-dark .jstree-disabled { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default-dark .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default-dark .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark > .jstree-striped { + background-size: auto 48px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default-dark .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default-dark .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default-dark > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark .jstree-ok, +#jstree-dnd.jstree-default-dark .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default-dark .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default-dark .jstree-er { + background-position: -36px -68px; +} +.jstree-default-dark .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-dark-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-dark-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-dark-small .jstree-wholerow { + height: 18px; +} +.jstree-default-dark-small .jstree-node, +.jstree-default-dark-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-dark-small .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-dark-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-dark-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-dark-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-node, +.jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-dark-small .jstree-disabled { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-dark-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-dark-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-dark-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-dark-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-dark-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok, +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-dark-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-dark-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-dark-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-dark-large .jstree-wholerow { + height: 32px; +} +.jstree-default-dark-large .jstree-node, +.jstree-default-dark-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-dark-large .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-dark-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-dark-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-dark-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-node, +.jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-dark-large .jstree-disabled { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-dark-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-dark-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-dark-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-dark-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-dark-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok, +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-dark-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-dark-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-dark-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-dark-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-dark-responsive .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-open > .jstree-ocl { + background-position: 0 0 !important; + } + .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0 !important; + } + .jstree-default-dark-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-dark-responsive .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-dark-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-dark-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-dark-responsive .jstree-wholerow { + border-top: 1px solid #666; + border-bottom: 1px solid #000; + background: #333333; + height: 40px; + } + .jstree-default-dark-responsive .jstree-wholerow-hovered { + background: #555; + } + .jstree-default-dark-responsive .jstree-wholerow-clicked { + background: #5fa2db; + } + .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #111111; + } + .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #111111; + border-top: 0; + } + .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-node > .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-dark-responsive .jstree-last { + background: transparent; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-dark-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-dark-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-dark-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} +.jstree-default-dark { + background: #333; +} +.jstree-default-dark .jstree-anchor { + color: #999; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); +} +.jstree-default-dark .jstree-clicked, +.jstree-default-dark .jstree-checked { + color: white; +} +.jstree-default-dark .jstree-hovered { + color: white; +} +#jstree-marker.jstree-default-dark { + border-left-color: #999; + background: transparent; +} +.jstree-default-dark .jstree-anchor > .jstree-icon { + opacity: 0.75; +} +.jstree-default-dark .jstree-clicked > .jstree-icon, +.jstree-default-dark .jstree-hovered > .jstree-icon, +.jstree-default-dark .jstree-checked > .jstree-icon { + opacity: 1; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/style.min.css b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/style.min.css new file mode 100644 index 00000000..fb1d236f --- /dev/null +++ b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default-dark .jstree-anchor,.jstree-default-dark .jstree-animated,.jstree-default-dark .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default-dark .jstree-hovered{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-context{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-clicked{background:#5fa2db;border-radius:2px;box-shadow:inset 0 0 1px #666666}.jstree-default-dark .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default-dark .jstree-disabled{background:transparent;color:#666666}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#333333}.jstree-default-dark .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark .jstree-search{font-style:italic;color:#ffffff;font-weight:bold}.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#555}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#555}.jstree-default-dark>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default-dark>.jstree-wholerow-ul .jstree-hovered,.jstree-default-dark>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default-dark .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default-dark .jstree-wholerow-hovered{background:#555}.jstree-default-dark .jstree-wholerow-clicked{background:#5fa2db;background:-webkit-linear-gradient(top, #5fa2db 0, #5fa2db 100%);background:linear-gradient(to bottom, #5fa2db 0, #5fa2db 100%)}.jstree-default-dark .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default-dark .jstree-anchor{line-height:24px;height:24px}.jstree-default-dark .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default-dark .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default-dark.jstree-rtl .jstree-node{margin-right:24px}.jstree-default-dark .jstree-wholerow{height:24px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-image:url("32px.png")}.jstree-default-dark .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default-dark .jstree-last{background:transparent}.jstree-default-dark .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default-dark .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default-dark .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default-dark .jstree-themeicon{background-position:-260px -4px}.jstree-default-dark>.jstree-no-dots .jstree-node,.jstree-default-dark>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default-dark>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default-dark .jstree-disabled{background:transparent}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark .jstree-checkbox{background-position:-164px -4px}.jstree-default-dark .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default-dark .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default-dark .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default-dark .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark>.jstree-striped{background-size:auto 48px}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default-dark.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default-dark.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default-dark .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default-dark .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default-dark>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default-dark .jstree-ok,#jstree-dnd.jstree-default-dark .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default-dark .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default-dark .jstree-er{background-position:-36px -68px}.jstree-default-dark .jstree-ellipsis{overflow:hidden}.jstree-default-dark .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-dark-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-dark-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-dark-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-dark-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-dark-small .jstree-wholerow{height:18px}.jstree-default-dark-small .jstree-node,.jstree-default-dark-small .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-dark-small .jstree-last{background:transparent}.jstree-default-dark-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-dark-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-dark-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-dark-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-node,.jstree-default-dark-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-dark-small .jstree-disabled{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-dark-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-dark-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-small>.jstree-striped{background-size:auto 36px}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-dark-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-dark-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-dark-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-dark-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-dark-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-dark-small .jstree-ok,#jstree-dnd.jstree-default-dark-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-dark-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-dark-small .jstree-er{background-position:-39px -71px}.jstree-default-dark-small .jstree-ellipsis{overflow:hidden}.jstree-default-dark-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-dark-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-dark-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-dark-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-dark-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-dark-large .jstree-wholerow{height:32px}.jstree-default-dark-large .jstree-node,.jstree-default-dark-large .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-dark-large .jstree-last{background:transparent}.jstree-default-dark-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-dark-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-dark-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-dark-large .jstree-themeicon{background-position:-256px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-node,.jstree-default-dark-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-dark-large .jstree-disabled{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-large .jstree-checkbox{background-position:-160px 0}.jstree-default-dark-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-dark-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-large>.jstree-striped{background-size:auto 64px}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-dark-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-dark-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-dark-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-dark-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-dark-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-dark-large .jstree-ok,#jstree-dnd.jstree-default-dark-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-dark-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-dark-large .jstree-er{background-position:-32px -64px}.jstree-default-dark-large .jstree-ellipsis{overflow:hidden}.jstree-default-dark-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-dark-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-dark-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-dark-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-dark-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-dark-responsive .jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl,.jstree-default-dark-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-dark-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-dark-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-dark-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-dark-responsive .jstree-checkbox,.jstree-default-dark-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-dark-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-dark-responsive>.jstree-striped{background:transparent}.jstree-default-dark-responsive .jstree-wholerow{border-top:1px solid #666;border-bottom:1px solid #000;background:#333333;height:40px}.jstree-default-dark-responsive .jstree-wholerow-hovered{background:#555}.jstree-default-dark-responsive .jstree-wholerow-clicked{background:#5fa2db}.jstree-default-dark-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #111111}.jstree-default-dark-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #111111;border-top:0}.jstree-default-dark-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-node>.jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-dark-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-dark-responsive .jstree-last{background:transparent}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-dark-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-dark-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}.jstree-default-dark{background:#333}.jstree-default-dark .jstree-anchor{color:#999;text-shadow:1px 1px 0 rgba(0,0,0,0.5)}.jstree-default-dark .jstree-clicked,.jstree-default-dark .jstree-checked{color:white}.jstree-default-dark .jstree-hovered{color:white}#jstree-marker.jstree-default-dark{border-left-color:#999;background:transparent}.jstree-default-dark .jstree-anchor>.jstree-icon{opacity:.75}.jstree-default-dark .jstree-clicked>.jstree-icon,.jstree-default-dark .jstree-hovered>.jstree-icon,.jstree-default-dark .jstree-checked>.jstree-icon{opacity:1}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent} \ No newline at end of file diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/throbber.gif b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/throbber.gif new file mode 100644 index 00000000..169062cd Binary files /dev/null and b/web/help/taseditor/vendors/jstree-3.3.10/themes/default-dark/throbber.gif differ diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default/32px.png b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/32px.png new file mode 100644 index 00000000..ca6af206 Binary files /dev/null and b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/32px.png differ diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default/40px.png b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/40px.png new file mode 100644 index 00000000..2a3fcb9d Binary files /dev/null and b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/40px.png differ diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default/style.css b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/style.css new file mode 100644 index 00000000..0703168b --- /dev/null +++ b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/style.css @@ -0,0 +1,1102 @@ +/* jsTree default theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.jstree-contextmenu .jstree-anchor { + -webkit-user-select: none; + /* disable selection/Copy of UIWebView */ + -webkit-touch-callout: none; + /* disable the IOS popup when long-press on a link */ +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context .vakata-contextmenu-disabled > a > i { + filter: grayscale(100%); +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default .jstree-anchor, +.jstree-default .jstree-animated, +.jstree-default .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default .jstree-hovered { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-context { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-clicked { + background: #beebff; + border-radius: 2px; + box-shadow: inset 0 0 1px #999999; +} +.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default .jstree-search { + font-style: italic; + color: #8b0000; + font-weight: bold; +} +.jstree-default .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #e7f4f9; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default > .jstree-wholerow-ul .jstree-hovered, +.jstree-default > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default .jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default .jstree-wholerow-clicked { + background: #beebff; + background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); + background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); +} +.jstree-default .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default .jstree-wholerow { + height: 24px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default .jstree-last { + background: transparent; +} +.jstree-default .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default > .jstree-no-dots .jstree-node, +.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default .jstree-disabled { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default > .jstree-striped { + background-size: auto 48px; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default .jstree-ok, +#jstree-dnd.jstree-default .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default .jstree-er { + background-position: -36px -68px; +} +.jstree-default .jstree-ellipsis { + overflow: hidden; +} +.jstree-default .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-small .jstree-wholerow { + height: 18px; +} +.jstree-default-small .jstree-node, +.jstree-default-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-small .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-node, +.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-small .jstree-disabled { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-small .jstree-ok, +#jstree-dnd.jstree-default-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-large .jstree-wholerow { + height: 32px; +} +.jstree-default-large .jstree-node, +.jstree-default-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-large .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-node, +.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-large .jstree-disabled { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-large .jstree-ok, +#jstree-dnd.jstree-default-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-responsive .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-open > .jstree-ocl { + background-position: 0 0 !important; + } + .jstree-default-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0 !important; + } + .jstree-default-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-responsive .jstree-checkbox, + .jstree-default-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-responsive .jstree-wholerow { + border-top: 1px solid rgba(255, 255, 255, 0.7); + border-bottom: 1px solid rgba(64, 64, 64, 0.2); + background: #ebebeb; + height: 40px; + } + .jstree-default-responsive .jstree-wholerow-hovered { + background: #e7f4f9; + } + .jstree-default-responsive .jstree-wholerow-clicked { + background: #beebff; + } + .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #666666; + } + .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #666666; + border-top: 0; + } + .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-node > .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-responsive .jstree-last { + background: transparent; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default/style.min.css b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/style.min.css new file mode 100644 index 00000000..93f80e91 --- /dev/null +++ b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:transparent}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:transparent}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:transparent}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:transparent}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file diff --git a/web/help/taseditor/vendors/jstree-3.3.10/themes/default/throbber.gif b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/throbber.gif new file mode 100644 index 00000000..cf06c1ad Binary files /dev/null and b/web/help/taseditor/vendors/jstree-3.3.10/themes/default/throbber.gif differ diff --git a/web/help/taseditor/vendors/markjs-8.11.1/jquery.mark.min.js b/web/help/taseditor/vendors/markjs-8.11.1/jquery.mark.min.js new file mode 100644 index 00000000..197e3123 --- /dev/null +++ b/web/help/taseditor/vendors/markjs-8.11.1/jquery.mark.min.js @@ -0,0 +1,7 @@ +/*!*************************************************** +* mark.js v8.11.1 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):e.Mark=t(e.jQuery)}(this,function(e){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e;var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},r=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;n(this,e),this.ctx=t,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return r(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t=e.getAttribute("src").trim();return"about:blank"===e.contentWindow.location.href&&"about:blank"!==t&&t}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(function(t){return!r.call(e,t)||(i=!0,!1)}),i}return!1}}]),e}(),a=function(){function e(t){n(this,e),this.ctx=t,this.ie=!1;var r=window.navigator.userAgent;(r.indexOf("MSIE")>-1||r.indexOf("Trident")>-1)&&(this.ie=!0)}return r(e,[{key:"log",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":t(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+e)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynomyms(a)+"|"+this.processSynomyms(s)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(i){n.every(function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,i="";switch(("string"==typeof n?[]:n.limiters).forEach(function(e){i+="|"+t.escapeStr(e)}),r){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var i=t.callNoMatchOnInvalidRanges(e,r),o=i.start,a=i.end;i.valid&&(e.start=o,e.length=a-o,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,o=n.length,a=t-o,s=parseInt(e.start,10)-a;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return o.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),o=i.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=i.textContent,i.parentNode.replaceChild(a,i),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var o=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=o.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,i(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapMatches",value:function(e,t,n,r,i){var o=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[a];)if(n(i[a],t)){var s=i.index;if(0!==a)for(var c=1;c #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;bE;E++)if("0"===m[0]&&1E&&(m=k,E=z)):"0"===l[q]&&(p=!0,k=q,z=1);z>E&&(m=k,E=z);1=L&&D>>10&1023|55296),t=56320|t&1023);return D+=y(t)}).join("")}function E(n,t){return n+22+75*(26>n)-((0!=t)<<5)}function z(n,t,D){var x=0;n=D?g(n/700):n>>1;for(n+=g(n/t);455e&&(e=0);for(b=0;b=D&&w("invalid-input");var h=n.charCodeAt(e++); +h=10>h-48?h-22:26>h-65?h-65:26>h-97?h-97:36;(36<=h||h>g((2147483647-x)/f))&&w("overflow");x+=h*f;var A=c<=a?1:c>=a+26?26:c-a;if(hg(2147483647/h)&&w("overflow");f*=h}f=t.length+1;a=z(x-b,f,0==b);g(x/f)>2147483647-L&&w("overflow");L+=g(x/f);x%=f;t.splice(x++,0,L)}return q(t)}function p(n){var t,D,x,L=[];n=d(n);var a=n.length;var b=128;var c=0;var e=72;for(x=0;xf&&L.push(y(f))}for((t=D=L.length)&&L.push("-");t=b&& +fg((2147483647-c)/A)&&w("overflow");c+=(h-b)*A;b=h;for(x=0;x=e+26?26:h-e;if(J= 0x80 (not a basic code point)","invalid-input":"Invalid input"},g=Math.floor,y=String.fromCharCode,H;var G={version:"1.3.2",ucs2:{decode:d,encode:q},decode:k,encode:p,toASCII:function(n){return m(n,function(t){return u.test(t)?"xn--"+p(t):t})},toUnicode:function(n){return m(n,function(t){return F.test(t)?k(t.slice(4).toLowerCase()): +t})}};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return G});else if(B&&v)if(module.exports==B)v.exports=G;else for(H in G)G.hasOwnProperty(H)&&(B[H]=G[H]);else r.punycode=G})(this); +(function(r,w){"object"===typeof module&&module.exports?module.exports=w():"function"===typeof define&&define.amd?define(w):r.SecondLevelDomains=w(r)})(this,function(r){var w=r&&r.SecondLevelDomains,l={list:{ac:" com gov mil net org ",ae:" ac co gov mil name net org pro sch ",af:" com edu gov net org ",al:" com edu gov mil net org ",ao:" co ed gv it og pb ",ar:" com edu gob gov int mil net org tur ",at:" ac co gv or ",au:" asn com csiro edu gov id net org ",ba:" co com edu gov mil net org rs unbi unmo unsa untz unze ", +bb:" biz co com edu gov info net org store tv ",bh:" biz cc com edu gov info net org ",bn:" com edu gov net org ",bo:" com edu gob gov int mil net org tv ",br:" adm adv agr am arq art ato b bio blog bmd cim cng cnt com coop ecn edu eng esp etc eti far flog fm fnd fot fst g12 ggf gov imb ind inf jor jus lel mat med mil mus net nom not ntr odo org ppg pro psc psi qsl rec slg srv tmp trd tur tv vet vlog wiki zlg ",bs:" com edu gov net org ",bz:" du et om ov rg ",ca:" ab bc mb nb nf nl ns nt nu on pe qc sk yk ", +ck:" biz co edu gen gov info net org ",cn:" ac ah bj com cq edu fj gd gov gs gx gz ha hb he hi hl hn jl js jx ln mil net nm nx org qh sc sd sh sn sx tj tw xj xz yn zj ",co:" com edu gov mil net nom org ",cr:" ac c co ed fi go or sa ",cy:" ac biz com ekloges gov ltd name net org parliament press pro tm ","do":" art com edu gob gov mil net org sld web ",dz:" art asso com edu gov net org pol ",ec:" com edu fin gov info med mil net org pro ",eg:" com edu eun gov mil name net org sci ",er:" com edu gov ind mil net org rochest w ", +es:" com edu gob nom org ",et:" biz com edu gov info name net org ",fj:" ac biz com info mil name net org pro ",fk:" ac co gov net nom org ",fr:" asso com f gouv nom prd presse tm ",gg:" co net org ",gh:" com edu gov mil org ",gn:" ac com gov net org ",gr:" com edu gov mil net org ",gt:" com edu gob ind mil net org ",gu:" com edu gov net org ",hk:" com edu gov idv net org ",hu:" 2000 agrar bolt casino city co erotica erotika film forum games hotel info ingatlan jogasz konyvelo lakas media news org priv reklam sex shop sport suli szex tm tozsde utazas video ", +id:" ac co go mil net or sch web ",il:" ac co gov idf k12 muni net org ","in":" ac co edu ernet firm gen gov i ind mil net nic org res ",iq:" com edu gov i mil net org ",ir:" ac co dnssec gov i id net org sch ",it:" edu gov ",je:" co net org ",jo:" com edu gov mil name net org sch ",jp:" ac ad co ed go gr lg ne or ",ke:" ac co go info me mobi ne or sc ",kh:" com edu gov mil net org per ",ki:" biz com de edu gov info mob net org tel ",km:" asso com coop edu gouv k medecin mil nom notaires pharmaciens presse tm veterinaire ", +kn:" edu gov net org ",kr:" ac busan chungbuk chungnam co daegu daejeon es gangwon go gwangju gyeongbuk gyeonggi gyeongnam hs incheon jeju jeonbuk jeonnam k kg mil ms ne or pe re sc seoul ulsan ",kw:" com edu gov net org ",ky:" com edu gov net org ",kz:" com edu gov mil net org ",lb:" com edu gov net org ",lk:" assn com edu gov grp hotel int ltd net ngo org sch soc web ",lr:" com edu gov net org ",lv:" asn com conf edu gov id mil net org ",ly:" com edu gov id med net org plc sch ",ma:" ac co gov m net org press ", +mc:" asso tm ",me:" ac co edu gov its net org priv ",mg:" com edu gov mil nom org prd tm ",mk:" com edu gov inf name net org pro ",ml:" com edu gov net org presse ",mn:" edu gov org ",mo:" com edu gov net org ",mt:" com edu gov net org ",mv:" aero biz com coop edu gov info int mil museum name net org pro ",mw:" ac co com coop edu gov int museum net org ",mx:" com edu gob net org ",my:" com edu gov mil name net org sch ",nf:" arts com firm info net other per rec store web ",ng:" biz com edu gov mil mobi name net org sch ", +ni:" ac co com edu gob mil net nom org ",np:" com edu gov mil net org ",nr:" biz com edu gov info net org ",om:" ac biz co com edu gov med mil museum net org pro sch ",pe:" com edu gob mil net nom org sld ",ph:" com edu gov i mil net ngo org ",pk:" biz com edu fam gob gok gon gop gos gov net org web ",pl:" art bialystok biz com edu gda gdansk gorzow gov info katowice krakow lodz lublin mil net ngo olsztyn org poznan pwr radom slupsk szczecin torun warszawa waw wroc wroclaw zgora ",pr:" ac biz com edu est gov info isla name net org pro prof ", +ps:" com edu gov net org plo sec ",pw:" belau co ed go ne or ",ro:" arts com firm info nom nt org rec store tm www ",rs:" ac co edu gov in org ",sb:" com edu gov net org ",sc:" com edu gov net org ",sh:" co com edu gov net nom org ",sl:" com edu gov net org ",st:" co com consulado edu embaixada gov mil net org principe saotome store ",sv:" com edu gob org red ",sz:" ac co org ",tr:" av bbs bel biz com dr edu gen gov info k12 name net org pol tel tsk tv web ",tt:" aero biz cat co com coop edu gov info int jobs mil mobi museum name net org pro tel travel ", +tw:" club com ebiz edu game gov idv mil net org ",mu:" ac co com gov net or org ",mz:" ac co edu gov org ",na:" co com ",nz:" ac co cri geek gen govt health iwi maori mil net org parliament school ",pa:" abo ac com edu gob ing med net nom org sld ",pt:" com edu gov int net nome org publ ",py:" com edu gov mil net org ",qa:" com edu gov mil net org ",re:" asso com nom ",ru:" ac adygeya altai amur arkhangelsk astrakhan bashkiria belgorod bir bryansk buryatia cbg chel chelyabinsk chita chukotka chuvashia com dagestan e-burg edu gov grozny int irkutsk ivanovo izhevsk jar joshkar-ola kalmykia kaluga kamchatka karelia kazan kchr kemerovo khabarovsk khakassia khv kirov koenig komi kostroma kranoyarsk kuban kurgan kursk lipetsk magadan mari mari-el marine mil mordovia mosreg msk murmansk nalchik net nnov nov novosibirsk nsk omsk orenburg org oryol penza perm pp pskov ptz rnd ryazan sakhalin samara saratov simbirsk smolensk spb stavropol stv surgut tambov tatarstan tom tomsk tsaritsyn tsk tula tuva tver tyumen udm udmurtia ulan-ude vladikavkaz vladimir vladivostok volgograd vologda voronezh vrn vyatka yakutia yamal yekaterinburg yuzhno-sakhalinsk ", +rw:" ac co com edu gouv gov int mil net ",sa:" com edu gov med net org pub sch ",sd:" com edu gov info med net org tv ",se:" a ac b bd c d e f g h i k l m n o org p parti pp press r s t tm u w x y z ",sg:" com edu gov idn net org per ",sn:" art com edu gouv org perso univ ",sy:" com edu gov mil net news org ",th:" ac co go in mi net or ",tj:" ac biz co com edu go gov info int mil name net nic org test web ",tn:" agrinet com defense edunet ens fin gov ind info intl mincom nat net org perso rnrt rns rnu tourism ", +tz:" ac co go ne or ",ua:" biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ",ug:" ac co go ne or org sc ",uk:" ac bl british-library co cym gov govt icnet jet lea ltd me mil mod national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ", +us:" dni fed isa kids nsn ",uy:" com edu gub mil net org ",ve:" co com edu gob info mil net org web ",vi:" co com k12 net org ",vn:" ac biz com edu gov health info int name net org pro ",ye:" co com gov ltd me net org plc ",yu:" ac co edu gov org ",za:" ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ",zm:" ac co com edu gov net org sch ",com:"ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ",net:"gb jp se uk ", +org:"ae",de:"com "},has:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return!1;var q=m.lastIndexOf(".",d-1);if(0>=q||q>=d-1)return!1;var E=l.list[m.slice(d+1)];return E?0<=E.indexOf(" "+m.slice(q+1,d)+" "):!1},is:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1||0<=m.lastIndexOf(".",d-1))return!1;var q=l.list[m.slice(d+1)];return q?0<=q.indexOf(" "+m.slice(0,d)+" "):!1},get:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return null;var q=m.lastIndexOf(".",d-1); +if(0>=q||q>=d-1)return null;var E=l.list[m.slice(d+1)];return!E||0>E.indexOf(" "+m.slice(q+1,d)+" ")?null:m.slice(q+1)},noConflict:function(){r.SecondLevelDomains===this&&(r.SecondLevelDomains=w);return this}};return l}); +(function(r,w){"object"===typeof module&&module.exports?module.exports=w(require("./punycode"),require("./IPv6"),require("./SecondLevelDomains")):"function"===typeof define&&define.amd?define(["./punycode","./IPv6","./SecondLevelDomains"],w):r.URI=w(r.punycode,r.IPv6,r.SecondLevelDomains,r)})(this,function(r,w,l,m){function d(a,b){var c=1<=arguments.length,e=2<=arguments.length;if(!(this instanceof d))return c?e?new d(a,b):new d(a):new d;if(void 0===a){if(c)throw new TypeError("undefined is not a valid argument for URI"); +a="undefined"!==typeof location?location.href+"":""}if(null===a&&c)throw new TypeError("null is not a valid argument for URI");this.href(a);return void 0!==b?this.absoluteTo(b):this}function q(a){return a.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function E(a){return void 0===a?"Undefined":String(Object.prototype.toString.call(a)).slice(8,-1)}function z(a){return"Array"===E(a)}function k(a,b){var c={},e;if("RegExp"===E(b))c=null;else if(z(b)){var f=0;for(e=b.length;f]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u2018\u2019]))/ig;d.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u201e\u2018\u2019]+$/,parens:/(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g};d.defaultPorts={http:"80",https:"443",ftp:"21", +gopher:"70",ws:"80",wss:"443"};d.hostProtocols=["http","https"];d.invalid_hostname_characters=/[^a-zA-Z0-9\.\-:_]/;d.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"};d.getDomAttribute=function(a){if(a&&a.nodeName){var b=a.nodeName.toLowerCase();if("input"!==b||"image"===a.type)return d.domAttributes[b]}};d.encode=F;d.decode=decodeURIComponent;d.iso8859= +function(){d.encode=escape;d.decode=unescape};d.unicode=function(){d.encode=F;d.decode=decodeURIComponent};d.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/ig,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@", +"%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}};d.encodeQuery=function(a,b){var c=d.encode(a+"");void 0===b&&(b=d.escapeQuerySpace);return b?c.replace(/%20/g,"+"):c};d.decodeQuery= +function(a,b){a+="";void 0===b&&(b=d.escapeQuerySpace);try{return d.decode(b?a.replace(/\+/g,"%20"):a)}catch(c){return a}};var H={encode:"encode",decode:"decode"},G,n=function(a,b){return function(c){try{return d[b](c+"").replace(d.characters[a][b].expression,function(e){return d.characters[a][b].map[e]})}catch(e){return c}}};for(G in H)d[G+"PathSegment"]=n("pathname",H[G]),d[G+"UrnPathSegment"]=n("urnpath",H[G]);H=function(a,b,c){return function(e){var f=c?function(J){return d[b](d[c](J))}:d[b]; +e=(e+"").split(a);for(var h=0,A=e.length;he)return a.charAt(0)===b.charAt(0)&&"/"===a.charAt(0)?"/":"";if("/"!==a.charAt(e)||"/"!==b.charAt(e))e=a.substring(0,e).lastIndexOf("/");return a.substring(0,e+1)};d.withinString=function(a,b,c){c||(c={});var e=c.start||d.findUri.start,f=c.end||d.findUri.end,h=c.trim||d.findUri.trim,A=c.parens||d.findUri.parens,J=/[a-z0-9-]=["']?$/i; +for(e.lastIndex=0;;){var M=e.exec(a);if(!M)break;var P=M.index;if(c.ignoreHtml){var N=a.slice(Math.max(P-3,0),P);if(N&&J.test(N))continue}var O=P+a.slice(P).search(f);N=a.slice(P,O);for(O=-1;;){var Q=A.exec(N);if(!Q)break;O=Math.max(O,Q.index+Q[0].length)}N=-1b))throw new TypeError('Port "'+a+'" is not a valid port');}};d.noConflict=function(a){if(a)return a={URI:this.noConflict()},m.URITemplate&&"function"===typeof m.URITemplate.noConflict&&(a.URITemplate=m.URITemplate.noConflict()),m.IPv6&&"function"===typeof m.IPv6.noConflict&&(a.IPv6=m.IPv6.noConflict()),m.SecondLevelDomains&&"function"===typeof m.SecondLevelDomains.noConflict&&(a.SecondLevelDomains=m.SecondLevelDomains.noConflict()),a;m.URI===this&&(m.URI= +C);return this};g.build=function(a){if(!0===a)this._deferred_build=!0;else if(void 0===a||this._deferred_build)this._string=d.build(this._parts),this._deferred_build=!1;return this};g.clone=function(){return new d(this)};g.valueOf=g.toString=function(){return this.build(!1)._string};g.protocol=u("protocol");g.username=u("username");g.password=u("password");g.hostname=u("hostname");g.port=u("port");g.query=I("query","?");g.fragment=I("fragment","#");g.search=function(a,b){var c=this.query(a,b);return"string"=== +typeof c&&c.length?"?"+c:c};g.hash=function(a,b){var c=this.fragment(a,b);return"string"===typeof c&&c.length?"#"+c:c};g.pathname=function(a,b){if(void 0===a||!0===a){var c=this._parts.path||(this._parts.hostname?"/":"");return a?(this._parts.urn?d.decodeUrnPath:d.decodePath)(c):c}this._parts.path=this._parts.urn?a?d.recodeUrnPath(a):"":a?d.recodePath(a):"/";this.build(!b);return this};g.path=g.pathname;g.href=function(a,b){var c;if(void 0===a)return this.toString();this._string="";this._parts=d._parts(); +var e=a instanceof d,f="object"===typeof a&&(a.hostname||a.path||a.pathname);a.nodeName&&(f=d.getDomAttribute(a),a=a[f]||"",f=!1);!e&&f&&void 0!==a.pathname&&(a=a.toString());if("string"===typeof a||a instanceof String)this._parts=d.parse(String(a),this._parts);else if(e||f){e=e?a._parts:a;for(c in e)"query"!==c&&y.call(this._parts,c)&&(this._parts[c]=e[c]);e.query&&this.query(e.query,!1)}else throw new TypeError("invalid input");this.build(!b);return this};g.is=function(a){var b=!1,c=!1,e=!1,f=!1, +h=!1,A=!1,J=!1,M=!this._parts.urn;this._parts.hostname&&(M=!1,c=d.ip4_expression.test(this._parts.hostname),e=d.ip6_expression.test(this._parts.hostname),b=c||e,h=(f=!b)&&l&&l.has(this._parts.hostname),A=f&&d.idn_expression.test(this._parts.hostname),J=f&&d.punycode_expression.test(this._parts.hostname));switch(a.toLowerCase()){case "relative":return M;case "absolute":return!M;case "domain":case "name":return f;case "sld":return h;case "ip":return b;case "ip4":case "ipv4":case "inet4":return c;case "ip6":case "ipv6":case "inet6":return e; +case "idn":return A;case "url":return!this._parts.urn;case "urn":return!!this._parts.urn;case "punycode":return J}return null};var t=g.protocol,D=g.port,x=g.hostname;g.protocol=function(a,b){if(a&&(a=a.replace(/:(\/\/)?$/,""),!a.match(d.protocol_expression)))throw new TypeError('Protocol "'+a+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return t.call(this,a,b)};g.scheme=g.protocol;g.port=function(a,b){if(this._parts.urn)return void 0===a?"":this;void 0!==a&&(0===a&& +(a=null),a&&(a+="",":"===a.charAt(0)&&(a=a.substring(1)),d.ensureValidPort(a)));return D.call(this,a,b)};g.hostname=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0!==a){var c={preventInvalidHostname:this._parts.preventInvalidHostname};if("/"!==d.parseHost(a,c))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');a=c.hostname;this._parts.preventInvalidHostname&&d.ensureValidHostname(a,this._parts.protocol)}return x.call(this,a,b)};g.origin=function(a, +b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){var c=this.protocol();return this.authority()?(c?c+"://":"")+this.authority():""}c=d(a);this.protocol(c.protocol()).authority(c.authority()).build(!b);return this};g.host=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildHost(this._parts):"";if("/"!==d.parseHost(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);return this}; +g.authority=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildAuthority(this._parts):"";if("/"!==d.parseAuthority(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);return this};g.userinfo=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){var c=d.buildUserinfo(this._parts);return c?c.substring(0,c.length-1):c}"@"!==a[a.length-1]&&(a+="@");d.parseUserinfo(a, +this._parts);this.build(!b);return this};g.resource=function(a,b){if(void 0===a)return this.path()+this.search()+this.hash();var c=d.parse(a);this._parts.path=c.path;this._parts.query=c.query;this._parts.fragment=c.fragment;this.build(!b);return this};g.subdomain=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,c)||""}c=this._parts.hostname.length- +this.domain().length;c=this._parts.hostname.substring(0,c);c=new RegExp("^"+q(c));a&&"."!==a.charAt(a.length-1)&&(a+=".");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");a&&d.ensureValidHostname(a,this._parts.protocol);this._parts.hostname=this._parts.hostname.replace(c,a);this.build(!b);return this};g.domain=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c= +this._parts.hostname.match(/\./g);if(c&&2>c.length)return this._parts.hostname;c=this._parts.hostname.length-this.tld(b).length-1;c=this._parts.hostname.lastIndexOf(".",c-1)+1;return this._parts.hostname.substring(c)||""}if(!a)throw new TypeError("cannot set domain empty");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");d.ensureValidHostname(a,this._parts.protocol);!this._parts.hostname||this.is("IP")?this._parts.hostname=a:(c=new RegExp(q(this.domain())+"$"),this._parts.hostname= +this._parts.hostname.replace(c,a));this.build(!b);return this};g.tld=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c=this._parts.hostname.lastIndexOf(".");c=this._parts.hostname.substring(c+1);return!0!==b&&l&&l.list[c.toLowerCase()]?l.get(this._parts.hostname)||c:c}if(a)if(a.match(/[^a-zA-Z0-9-]/))if(l&&l.is(a))c=new RegExp(q(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(c, +a);else throw new TypeError('TLD "'+a+'" contains characters other than [A-Z0-9]');else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");c=new RegExp(q(this.tld())+"$");this._parts.hostname=this._parts.hostname.replace(c,a)}else throw new TypeError("cannot set TLD empty");this.build(!b);return this};g.directory=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a||!0===a){if(!this._parts.path&&!this._parts.hostname)return""; +if("/"===this._parts.path)return"/";var c=this._parts.path.length-this.filename().length-1;c=this._parts.path.substring(0,c)||(this._parts.hostname?"/":"");return a?d.decodePath(c):c}c=this._parts.path.length-this.filename().length;c=this._parts.path.substring(0,c);c=new RegExp("^"+q(c));this.is("relative")||(a||(a="/"),"/"!==a.charAt(0)&&(a="/"+a));a&&"/"!==a.charAt(a.length-1)&&(a+="/");a=d.recodePath(a);this._parts.path=this._parts.path.replace(c,a);this.build(!b);return this};g.filename=function(a, +b){if(this._parts.urn)return void 0===a?"":this;if("string"!==typeof a){if(!this._parts.path||"/"===this._parts.path)return"";var c=this._parts.path.lastIndexOf("/");c=this._parts.path.substring(c+1);return a?d.decodePathSegment(c):c}c=!1;"/"===a.charAt(0)&&(a=a.substring(1));a.match(/\.?\//)&&(c=!0);var e=new RegExp(q(this.filename())+"$");a=d.recodePath(a);this._parts.path=this._parts.path.replace(e,a);c?this.normalizePath(b):this.build(!b);return this};g.suffix=function(a,b){if(this._parts.urn)return void 0=== +a?"":this;if(void 0===a||!0===a){if(!this._parts.path||"/"===this._parts.path)return"";var c=this.filename(),e=c.lastIndexOf(".");if(-1===e)return"";c=c.substring(e+1);c=/^[a-z0-9%]+$/i.test(c)?c:"";return a?d.decodePathSegment(c):c}"."===a.charAt(0)&&(a=a.substring(1));if(c=this.suffix())e=a?new RegExp(q(c)+"$"):new RegExp(q("."+c)+"$");else{if(!a)return this;this._parts.path+="."+d.recodePath(a)}e&&(a=d.recodePath(a),this._parts.path=this._parts.path.replace(e,a));this.build(!b);return this};g.segment= +function(a,b,c){var e=this._parts.urn?":":"/",f=this.path(),h="/"===f.substring(0,1);f=f.split(e);void 0!==a&&"number"!==typeof a&&(c=b,b=a,a=void 0);if(void 0!==a&&"number"!==typeof a)throw Error('Bad segment "'+a+'", must be 0-based integer');h&&f.shift();0>a&&(a=Math.max(f.length+a,0));if(void 0===b)return void 0===a?f:f[a];if(null===a||void 0===f[a])if(z(b)){f=[];a=0;for(var A=b.length;a{}"`^| \\]/;l.expand=function(k,p,B){var v=z[k.operator],K=v.named?"Named":"Unnamed";k=k.variables;var F=[],u,I;for(I=0;u=k[I];I++){var C=p.get(u.name);if(0===C.type&&B&&B.strict)throw Error('Missing expansion value for variable "'+ +u.name+'"');if(C.val.length){if(1li>a:focus,.dropdown-menu>li>a:hover{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x;background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x;background-color:#2e6da4}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/web/help/vendors/bootstrap-3.4.1/css/bootstrap.min.css b/web/help/vendors/bootstrap-3.4.1/css/bootstrap.min.css new file mode 100644 index 00000000..455de954 --- /dev/null +++ b/web/help/vendors/bootstrap-3.4.1/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:"Glyphicons Halflings";src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),url(../fonts/glyphicons-halflings-regular.woff2) format("woff2"),url(../fonts/glyphicons-halflings-regular.woff) format("woff"),url(../fonts/glyphicons-halflings-regular.ttf) format("truetype"),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:"Glyphicons Halflings";font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-right:-15px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/web/help/vendors/bootstrap-3.4.1/css/ie10-viewport-bug-workaround.css b/web/help/vendors/bootstrap-3.4.1/css/ie10-viewport-bug-workaround.css new file mode 100644 index 00000000..8f7d32b0 --- /dev/null +++ b/web/help/vendors/bootstrap-3.4.1/css/ie10-viewport-bug-workaround.css @@ -0,0 +1,15 @@ +/*! + * IE10 viewport hack for Surface/desktop Windows 8 bug + * Copyright 2014-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/* + * See the Getting Started docs for more information: + * http://getbootstrap.com/getting-started/#support-ie10-width + */ +@-webkit-viewport { width: device-width; } +@-moz-viewport { width: device-width; } +@-ms-viewport { width: device-width; } +@-o-viewport { width: device-width; } +@viewport { width: device-width; } \ No newline at end of file diff --git a/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 00000000..b93a4953 Binary files /dev/null and b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot differ diff --git a/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..94fb5490 --- /dev/null +++ b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..1413fc60 Binary files /dev/null and b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf differ diff --git a/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..9e612858 Binary files /dev/null and b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff differ diff --git a/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 00000000..64539b54 Binary files /dev/null and b/web/help/vendors/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/web/help/vendors/bootstrap-3.4.1/js/bootstrap.min.js b/web/help/vendors/bootstrap-3.4.1/js/bootstrap.min.js new file mode 100644 index 00000000..eb0a8b41 --- /dev/null +++ b/web/help/vendors/bootstrap-3.4.1/js/bootstrap.min.js @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");!function(t){"use strict";var e=jQuery.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||3this.$items.length-1||t<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(idocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},s.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},s.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth
      ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0},sanitize:!0,sanitizeFn:null,whiteList:t},m.prototype.init=function(t,e,i){if(this.enabled=!0,this.type=t,this.$element=g(e),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&g(document).find(g.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var o=this.options.trigger.split(" "),n=o.length;n--;){var s=o[n];if("click"==s)this.$element.on("click."+this.type,this.options.selector,g.proxy(this.toggle,this));else if("manual"!=s){var a="hover"==s?"mouseenter":"focusin",r="hover"==s?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,g.proxy(this.enter,this)),this.$element.on(r+"."+this.type,this.options.selector,g.proxy(this.leave,this))}}this.options.selector?this._options=g.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},m.prototype.getDefaults=function(){return m.DEFAULTS},m.prototype.getOptions=function(t){var e=this.$element.data();for(var i in e)e.hasOwnProperty(i)&&-1!==g.inArray(i,o)&&delete e[i];return(t=g.extend({},this.getDefaults(),e,t)).delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t.sanitize&&(t.template=n(t.template,t.whiteList,t.sanitizeFn)),t},m.prototype.getDelegateOptions=function(){var i={},o=this.getDefaults();return this._options&&g.each(this._options,function(t,e){o[t]!=e&&(i[t]=e)}),i},m.prototype.enter=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusin"==t.type?"focus":"hover"]=!0),e.tip().hasClass("in")||"in"==e.hoverState)e.hoverState="in";else{if(clearTimeout(e.timeout),e.hoverState="in",!e.options.delay||!e.options.delay.show)return e.show();e.timeout=setTimeout(function(){"in"==e.hoverState&&e.show()},e.options.delay.show)}},m.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},m.prototype.leave=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusout"==t.type?"focus":"hover"]=!1),!e.isInStateTrue()){if(clearTimeout(e.timeout),e.hoverState="out",!e.options.delay||!e.options.delay.hide)return e.hide();e.timeout=setTimeout(function(){"out"==e.hoverState&&e.hide()},e.options.delay.hide)}},m.prototype.show=function(){var t=g.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(t);var e=g.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(t.isDefaultPrevented()||!e)return;var i=this,o=this.tip(),n=this.getUID(this.type);this.setContent(),o.attr("id",n),this.$element.attr("aria-describedby",n),this.options.animation&&o.addClass("fade");var s="function"==typeof this.options.placement?this.options.placement.call(this,o[0],this.$element[0]):this.options.placement,a=/\s?auto?\s?/i,r=a.test(s);r&&(s=s.replace(a,"")||"top"),o.detach().css({top:0,left:0,display:"block"}).addClass(s).data("bs."+this.type,this),this.options.container?o.appendTo(g(document).find(this.options.container)):o.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var l=this.getPosition(),h=o[0].offsetWidth,d=o[0].offsetHeight;if(r){var p=s,c=this.getPosition(this.$viewport);s="bottom"==s&&l.bottom+d>c.bottom?"top":"top"==s&&l.top-dc.width?"left":"left"==s&&l.left-ha.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.right&&(n.left=a.left+a.width-d)}return n},m.prototype.getTitle=function(){var t=this.$element,e=this.options;return t.attr("data-original-title")||("function"==typeof e.title?e.title.call(t[0]):e.title)},m.prototype.getUID=function(t){for(;t+=~~(1e6*Math.random()),document.getElementById(t););return t},m.prototype.tip=function(){if(!this.$tip&&(this.$tip=g(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},m.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},m.prototype.enable=function(){this.enabled=!0},m.prototype.disable=function(){this.enabled=!1},m.prototype.toggleEnabled=function(){this.enabled=!this.enabled},m.prototype.toggle=function(t){var e=this;t&&((e=g(t.currentTarget).data("bs."+this.type))||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e))),t?(e.inState.click=!e.inState.click,e.isInStateTrue()?e.enter(e):e.leave(e)):e.tip().hasClass("in")?e.leave(e):e.enter(e)},m.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})},m.prototype.sanitizeHtml=function(t){return n(t,this.options.whiteList,this.options.sanitizeFn)};var e=g.fn.tooltip;g.fn.tooltip=function i(o){return this.each(function(){var t=g(this),e=t.data("bs.tooltip"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.tooltip",e=new m(this,i)),"string"==typeof o&&e[o]())})},g.fn.tooltip.Constructor=m,g.fn.tooltip.noConflict=function(){return g.fn.tooltip=e,this}}(jQuery),function(n){"use strict";var s=function(t,e){this.init("popover",t,e)};if(!n.fn.tooltip)throw new Error("Popover requires tooltip.js");s.VERSION="3.4.1",s.DEFAULTS=n.extend({},n.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),((s.prototype=n.extend({},n.fn.tooltip.Constructor.prototype)).constructor=s).prototype.getDefaults=function(){return s.DEFAULTS},s.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();if(this.options.html){var o=typeof i;this.options.sanitize&&(e=this.sanitizeHtml(e),"string"===o&&(i=this.sanitizeHtml(i))),t.find(".popover-title").html(e),t.find(".popover-content").children().detach().end()["string"===o?"html":"append"](i)}else t.find(".popover-title").text(e),t.find(".popover-content").children().detach().end().text(i);t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},s.prototype.hasContent=function(){return this.getTitle()||this.getContent()},s.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},s.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var t=n.fn.popover;n.fn.popover=function e(o){return this.each(function(){var t=n(this),e=t.data("bs.popover"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.popover",e=new s(this,i)),"string"==typeof o&&e[o]())})},n.fn.popover.Constructor=s,n.fn.popover.noConflict=function(){return n.fn.popover=t,this}}(jQuery),function(s){"use strict";function n(t,e){this.$body=s(document.body),this.$scrollElement=s(t).is(document.body)?s(window):s(t),this.options=s.extend({},n.DEFAULTS,e),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",s.proxy(this.process,this)),this.refresh(),this.process()}function e(o){return this.each(function(){var t=s(this),e=t.data("bs.scrollspy"),i="object"==typeof o&&o;e||t.data("bs.scrollspy",e=new n(this,i)),"string"==typeof o&&e[o]()})}n.VERSION="3.4.1",n.DEFAULTS={offset:10},n.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},n.prototype.refresh=function(){var t=this,o="offset",n=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),s.isWindow(this.$scrollElement[0])||(o="position",n=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var t=s(this),e=t.data("target")||t.attr("href"),i=/^#./.test(e)&&s(e);return i&&i.length&&i.is(":visible")&&[[i[o]().top+n,e]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},n.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),o<=e)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(n[t+1]===undefined||e .active"),n=i&&r.support.transition&&(o.length&&o.hasClass("fade")||!!e.find("> .fade").length);function s(){o.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),t.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),n?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu").length&&t.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),i&&i()}o.length&&n?o.one("bsTransitionEnd",s).emulateTransitionEnd(a.TRANSITION_DURATION):s(),o.removeClass("in")};var t=r.fn.tab;r.fn.tab=e,r.fn.tab.Constructor=a,r.fn.tab.noConflict=function(){return r.fn.tab=t,this};var i=function(t){t.preventDefault(),e.call(r(this),"show")};r(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',i).on("click.bs.tab.data-api",'[data-toggle="pill"]',i)}(jQuery),function(l){"use strict";var h=function(t,e){this.options=l.extend({},h.DEFAULTS,e);var i=this.options.target===h.DEFAULTS.target?l(this.options.target):l(document).find(this.options.target);this.$target=i.on("scroll.bs.affix.data-api",l.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",l.proxy(this.checkPositionWithEventLoop,this)),this.$element=l(t),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};function i(o){return this.each(function(){var t=l(this),e=t.data("bs.affix"),i="object"==typeof o&&o;e||t.data("bs.affix",e=new h(this,i)),"string"==typeof o&&e[o]()})}h.VERSION="3.4.1",h.RESET="affix affix-top affix-bottom",h.DEFAULTS={offset:0,target:window},h.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return ns.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t,n){n=n||{},Object.assign(this,o.options,n),this.classes=Object.assign({},o.options.classes,n.classes),this.elem=t,this.tolerance=function(t){return t===Object(t)?t:{down:t,up:t}}(this.tolerance),this.initialised=!1,this.frozen=!1}return o.prototype={constructor:o,init:function(){return o.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},o.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},o.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),o}); \ No newline at end of file diff --git a/web/help/vendors/helpndoc-5/icons/0.png b/web/help/vendors/helpndoc-5/icons/0.png new file mode 100644 index 00000000..0189cda7 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/0.png differ diff --git a/web/help/vendors/helpndoc-5/icons/1.png b/web/help/vendors/helpndoc-5/icons/1.png new file mode 100644 index 00000000..01335b02 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/1.png differ diff --git a/web/help/vendors/helpndoc-5/icons/10.png b/web/help/vendors/helpndoc-5/icons/10.png new file mode 100644 index 00000000..86c1b70c Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/10.png differ diff --git a/web/help/vendors/helpndoc-5/icons/11.png b/web/help/vendors/helpndoc-5/icons/11.png new file mode 100644 index 00000000..60da1797 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/11.png differ diff --git a/web/help/vendors/helpndoc-5/icons/12.png b/web/help/vendors/helpndoc-5/icons/12.png new file mode 100644 index 00000000..7977cad2 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/12.png differ diff --git a/web/help/vendors/helpndoc-5/icons/13.png b/web/help/vendors/helpndoc-5/icons/13.png new file mode 100644 index 00000000..2d6b99eb Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/13.png differ diff --git a/web/help/vendors/helpndoc-5/icons/14.png b/web/help/vendors/helpndoc-5/icons/14.png new file mode 100644 index 00000000..c6150b5f Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/14.png differ diff --git a/web/help/vendors/helpndoc-5/icons/15.png b/web/help/vendors/helpndoc-5/icons/15.png new file mode 100644 index 00000000..58f205ff Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/15.png differ diff --git a/web/help/vendors/helpndoc-5/icons/16.png b/web/help/vendors/helpndoc-5/icons/16.png new file mode 100644 index 00000000..746f6c4e Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/16.png differ diff --git a/web/help/vendors/helpndoc-5/icons/17.png b/web/help/vendors/helpndoc-5/icons/17.png new file mode 100644 index 00000000..e450e6b6 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/17.png differ diff --git a/web/help/vendors/helpndoc-5/icons/18.png b/web/help/vendors/helpndoc-5/icons/18.png new file mode 100644 index 00000000..fae8d066 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/18.png differ diff --git a/web/help/vendors/helpndoc-5/icons/19.png b/web/help/vendors/helpndoc-5/icons/19.png new file mode 100644 index 00000000..557aa37b Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/19.png differ diff --git a/web/help/vendors/helpndoc-5/icons/2.png b/web/help/vendors/helpndoc-5/icons/2.png new file mode 100644 index 00000000..38870794 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/2.png differ diff --git a/web/help/vendors/helpndoc-5/icons/20.png b/web/help/vendors/helpndoc-5/icons/20.png new file mode 100644 index 00000000..cb6845bc Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/20.png differ diff --git a/web/help/vendors/helpndoc-5/icons/21.png b/web/help/vendors/helpndoc-5/icons/21.png new file mode 100644 index 00000000..bfb11c91 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/21.png differ diff --git a/web/help/vendors/helpndoc-5/icons/22.png b/web/help/vendors/helpndoc-5/icons/22.png new file mode 100644 index 00000000..17ed9c5b Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/22.png differ diff --git a/web/help/vendors/helpndoc-5/icons/23.png b/web/help/vendors/helpndoc-5/icons/23.png new file mode 100644 index 00000000..1c4a863b Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/23.png differ diff --git a/web/help/vendors/helpndoc-5/icons/24.png b/web/help/vendors/helpndoc-5/icons/24.png new file mode 100644 index 00000000..e91b518c Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/24.png differ diff --git a/web/help/vendors/helpndoc-5/icons/25.png b/web/help/vendors/helpndoc-5/icons/25.png new file mode 100644 index 00000000..00d2d5d3 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/25.png differ diff --git a/web/help/vendors/helpndoc-5/icons/26.png b/web/help/vendors/helpndoc-5/icons/26.png new file mode 100644 index 00000000..4952af63 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/26.png differ diff --git a/web/help/vendors/helpndoc-5/icons/27.png b/web/help/vendors/helpndoc-5/icons/27.png new file mode 100644 index 00000000..a61fe9bd Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/27.png differ diff --git a/web/help/vendors/helpndoc-5/icons/28.png b/web/help/vendors/helpndoc-5/icons/28.png new file mode 100644 index 00000000..52160f07 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/28.png differ diff --git a/web/help/vendors/helpndoc-5/icons/29.png b/web/help/vendors/helpndoc-5/icons/29.png new file mode 100644 index 00000000..06aa97cb Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/29.png differ diff --git a/web/help/vendors/helpndoc-5/icons/3.png b/web/help/vendors/helpndoc-5/icons/3.png new file mode 100644 index 00000000..b1c94138 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/3.png differ diff --git a/web/help/vendors/helpndoc-5/icons/30.png b/web/help/vendors/helpndoc-5/icons/30.png new file mode 100644 index 00000000..7b52276d Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/30.png differ diff --git a/web/help/vendors/helpndoc-5/icons/31.png b/web/help/vendors/helpndoc-5/icons/31.png new file mode 100644 index 00000000..02283dbb Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/31.png differ diff --git a/web/help/vendors/helpndoc-5/icons/32.png b/web/help/vendors/helpndoc-5/icons/32.png new file mode 100644 index 00000000..875843c5 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/32.png differ diff --git a/web/help/vendors/helpndoc-5/icons/33.png b/web/help/vendors/helpndoc-5/icons/33.png new file mode 100644 index 00000000..d64f1371 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/33.png differ diff --git a/web/help/vendors/helpndoc-5/icons/34.png b/web/help/vendors/helpndoc-5/icons/34.png new file mode 100644 index 00000000..a6d94c5d Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/34.png differ diff --git a/web/help/vendors/helpndoc-5/icons/35.png b/web/help/vendors/helpndoc-5/icons/35.png new file mode 100644 index 00000000..dfc87bf7 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/35.png differ diff --git a/web/help/vendors/helpndoc-5/icons/36.png b/web/help/vendors/helpndoc-5/icons/36.png new file mode 100644 index 00000000..ce6235b2 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/36.png differ diff --git a/web/help/vendors/helpndoc-5/icons/37.png b/web/help/vendors/helpndoc-5/icons/37.png new file mode 100644 index 00000000..01203304 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/37.png differ diff --git a/web/help/vendors/helpndoc-5/icons/38.png b/web/help/vendors/helpndoc-5/icons/38.png new file mode 100644 index 00000000..5334faee Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/38.png differ diff --git a/web/help/vendors/helpndoc-5/icons/39.png b/web/help/vendors/helpndoc-5/icons/39.png new file mode 100644 index 00000000..06e446b8 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/39.png differ diff --git a/web/help/vendors/helpndoc-5/icons/4.png b/web/help/vendors/helpndoc-5/icons/4.png new file mode 100644 index 00000000..6e5cfc09 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/4.png differ diff --git a/web/help/vendors/helpndoc-5/icons/40.png b/web/help/vendors/helpndoc-5/icons/40.png new file mode 100644 index 00000000..6d744dbe Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/40.png differ diff --git a/web/help/vendors/helpndoc-5/icons/41.png b/web/help/vendors/helpndoc-5/icons/41.png new file mode 100644 index 00000000..476edf46 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/41.png differ diff --git a/web/help/vendors/helpndoc-5/icons/5.png b/web/help/vendors/helpndoc-5/icons/5.png new file mode 100644 index 00000000..1df634fe Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/5.png differ diff --git a/web/help/vendors/helpndoc-5/icons/6.png b/web/help/vendors/helpndoc-5/icons/6.png new file mode 100644 index 00000000..947d9c40 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/6.png differ diff --git a/web/help/vendors/helpndoc-5/icons/7.png b/web/help/vendors/helpndoc-5/icons/7.png new file mode 100644 index 00000000..a3628866 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/7.png differ diff --git a/web/help/vendors/helpndoc-5/icons/8.png b/web/help/vendors/helpndoc-5/icons/8.png new file mode 100644 index 00000000..5bcd3eca Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/8.png differ diff --git a/web/help/vendors/helpndoc-5/icons/9.png b/web/help/vendors/helpndoc-5/icons/9.png new file mode 100644 index 00000000..3b4991d8 Binary files /dev/null and b/web/help/vendors/helpndoc-5/icons/9.png differ diff --git a/web/help/vendors/html5shiv-3.7.3/html5shiv.min.js b/web/help/vendors/html5shiv-3.7.3/html5shiv.min.js new file mode 100644 index 00000000..355afd10 --- /dev/null +++ b/web/help/vendors/html5shiv-3.7.3/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/web/help/vendors/imageMapResizer-1.0.10/imageMapResizer.min.js b/web/help/vendors/imageMapResizer-1.0.10/imageMapResizer.min.js new file mode 100644 index 00000000..09ad956e --- /dev/null +++ b/web/help/vendors/imageMapResizer-1.0.10/imageMapResizer.min.js @@ -0,0 +1,8 @@ +/*! Image Map Resizer (imageMapResizer.min.js ) - v1.0.10 - 2019-04-10 + * Desc: Resize HTML imageMap to scaled image. + * Copyright: (c) 2019 David J. Bradshaw - dave@bradshaw.net + * License: MIT + */ + +!function(){"use strict";function r(){function e(){var r={width:u.width/u.naturalWidth,height:u.height/u.naturalHeight},a={width:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-left"),10),height:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-top"),10)};i.forEach(function(e,t){var n=0;o[t].coords=e.split(",").map(function(e){var t=1==(n=1-n)?"width":"height";return a[t]+Math.floor(Number(e)*r[t])}).join(",")})}function t(e){return e.coords.replace(/ *, */g,",").replace(/ +/g,",")}function n(){clearTimeout(d),d=setTimeout(e,250)}function r(e){return document.querySelector('img[usemap="'+e+'"]')}var a=this,o=null,i=null,u=null,d=null;"function"!=typeof a._resize?(o=a.getElementsByTagName("area"),i=Array.prototype.map.call(o,t),u=r("#"+a.name)||r(a.name),a._resize=e,u.addEventListener("load",e,!1),window.addEventListener("focus",e,!1),window.addEventListener("resize",n,!1),window.addEventListener("readystatechange",e,!1),document.addEventListener("fullscreenchange",e,!1),u.width===u.naturalWidth&&u.height===u.naturalHeight||e()):a._resize()}function e(){function t(e){e&&(!function(e){if(!e.tagName)throw new TypeError("Object is not a valid DOM element");if("MAP"!==e.tagName.toUpperCase())throw new TypeError("Expected tag, found <"+e.tagName+">.")}(e),r.call(e),n.push(e))}var n;return function(e){switch(n=[],typeof e){case"undefined":case"string":Array.prototype.forEach.call(document.querySelectorAll(e||"map"),t);break;case"object":t(e);break;default:throw new TypeError("Unexpected data type ("+typeof e+").")}return n}}"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&"object"==typeof module.exports?module.exports=e():window.imageMapResize=e(),"jQuery"in window&&(window.jQuery.fn.imageMapResize=function(){return this.filter("map").each(r).end()})}(); +//# sourceMappingURL=imageMapResizer.map \ No newline at end of file diff --git a/web/help/vendors/interactjs-1.9.22/interact.min.js b/web/help/vendors/interactjs-1.9.22/interact.min.js new file mode 100644 index 00000000..420f876f --- /dev/null +++ b/web/help/vendors/interactjs-1.9.22/interact.min.js @@ -0,0 +1,3 @@ +/* interact.js 1.9.22 | https://raw.github.com/taye/interact.js/master/LICENSE */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).interact=t()}}((function(){var t={};Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default=function(t){return!(!t||!t.Window)&&t instanceof t.Window};var e={};Object.defineProperty(e,"__esModule",{value:!0}),e.init=o,e.getWindow=function(e){if((0,t.default)(e))return e;return(e.ownerDocument||e).defaultView||r.window},e.window=e.realWindow=void 0;var n=void 0;e.realWindow=n;var r=void 0;function o(t){e.realWindow=n=t;var o=t.document.createTextNode("");o.ownerDocument!==t.document&&"function"==typeof t.wrap&&t.wrap(o)===o&&(t=t.wrap(t)),e.window=r=t}e.window=r,"undefined"!=typeof window&&window&&o(window);var i={};function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}Object.defineProperty(i,"__esModule",{value:!0}),i.default=void 0;var s=function(t){return!!t&&"object"===a(t)},l=function(t){return"function"==typeof t},u={window:function(n){return n===e.window||(0,t.default)(n)},docFrag:function(t){return s(t)&&11===t.nodeType},object:s,func:l,number:function(t){return"number"==typeof t},bool:function(t){return"boolean"==typeof t},string:function(t){return"string"==typeof t},element:function(t){if(!t||"object"!==a(t))return!1;var n=e.getWindow(t)||e.window;return/object|function/.test(a(n.Element))?t instanceof n.Element:1===t.nodeType&&"string"==typeof t.nodeName},plainObject:function(t){return s(t)&&!!t.constructor&&/function Object\b/.test(t.constructor.toString())},array:function(t){return s(t)&&void 0!==t.length&&l(t.splice)}};i.default=u;var c={};function f(t){var e=t.interaction;if("drag"===e.prepared.name){var n=e.prepared.axis;"x"===n?(e.coords.cur.page.y=e.coords.start.page.y,e.coords.cur.client.y=e.coords.start.client.y,e.coords.velocity.client.y=0,e.coords.velocity.page.y=0):"y"===n&&(e.coords.cur.page.x=e.coords.start.page.x,e.coords.cur.client.x=e.coords.start.client.x,e.coords.velocity.client.x=0,e.coords.velocity.page.x=0)}}function d(t){var e=t.iEvent,n=t.interaction;if("drag"===n.prepared.name){var r=n.prepared.axis;if("x"===r||"y"===r){var o="x"===r?"y":"x";e.page[o]=n.coords.start.page[o],e.client[o]=n.coords.start.client[o],e.delta[o]=0}}}Object.defineProperty(c,"__esModule",{value:!0}),c.default=void 0;var p={id:"actions/drag",install:function(t){var e=t.actions,n=t.Interactable,r=t.defaults;n.prototype.draggable=p.draggable,e.map.drag=p,e.methodDict.drag="draggable",r.actions.drag=p.defaults},listeners:{"interactions:before-action-move":f,"interactions:action-resume":f,"interactions:action-move":d,"auto-start:check":function(t){var e=t.interaction,n=t.interactable,r=t.buttons,o=n.options.drag;if(o&&o.enabled&&(!e.pointerIsDown||!/mouse|pointer/.test(e.pointerType)||0!=(r&n.options.drag.mouseButtons)))return t.action={name:"drag",axis:"start"===o.lockAxis?o.startAxis:o.lockAxis},!1}},draggable:function(t){return i.default.object(t)?(this.options.drag.enabled=!1!==t.enabled,this.setPerAction("drag",t),this.setOnEvents("drag",t),/^(xy|x|y|start)$/.test(t.lockAxis)&&(this.options.drag.lockAxis=t.lockAxis),/^(xy|x|y)$/.test(t.startAxis)&&(this.options.drag.startAxis=t.startAxis),this):i.default.bool(t)?(this.options.drag.enabled=t,this):this.options.drag},beforeMove:f,move:d,defaults:{startAxis:"xy",lockAxis:"xy"},getCursor:function(){return"move"}},v=p;c.default=v;var h={};Object.defineProperty(h,"__esModule",{value:!0}),h.default=void 0;var g={init:function(t){var e=t;g.document=e.document,g.DocumentFragment=e.DocumentFragment||y,g.SVGElement=e.SVGElement||y,g.SVGSVGElement=e.SVGSVGElement||y,g.SVGElementInstance=e.SVGElementInstance||y,g.Element=e.Element||y,g.HTMLElement=e.HTMLElement||g.Element,g.Event=e.Event,g.Touch=e.Touch||y,g.PointerEvent=e.PointerEvent||e.MSPointerEvent},document:null,DocumentFragment:null,SVGElement:null,SVGSVGElement:null,SVGElementInstance:null,Element:null,HTMLElement:null,Event:null,Touch:null,PointerEvent:null};function y(){}var m=g;h.default=m;var b={};Object.defineProperty(b,"__esModule",{value:!0}),b.default=void 0;var x={init:function(t){var n=h.default.Element,r=e.window.navigator;x.supportsTouch="ontouchstart"in t||i.default.func(t.DocumentTouch)&&h.default.document instanceof t.DocumentTouch,x.supportsPointerEvent=!1!==r.pointerEnabled&&!!h.default.PointerEvent,x.isIOS=/iP(hone|od|ad)/.test(r.platform),x.isIOS7=/iP(hone|od|ad)/.test(r.platform)&&/OS 7[^\d]/.test(r.appVersion),x.isIe9=/MSIE 9/.test(r.userAgent),x.isOperaMobile="Opera"===r.appName&&x.supportsTouch&&/Presto/.test(r.userAgent),x.prefixedMatchesSelector="matches"in n.prototype?"matches":"webkitMatchesSelector"in n.prototype?"webkitMatchesSelector":"mozMatchesSelector"in n.prototype?"mozMatchesSelector":"oMatchesSelector"in n.prototype?"oMatchesSelector":"msMatchesSelector",x.pEventTypes=x.supportsPointerEvent?h.default.PointerEvent===t.MSPointerEvent?{up:"MSPointerUp",down:"MSPointerDown",over:"mouseover",out:"mouseout",move:"MSPointerMove",cancel:"MSPointerCancel"}:{up:"pointerup",down:"pointerdown",over:"pointerover",out:"pointerout",move:"pointermove",cancel:"pointercancel"}:null,x.wheelEvent="onmousewheel"in h.default.document?"mousewheel":"wheel"},supportsTouch:null,supportsPointerEvent:null,isIOS7:null,isIOS:null,isIe9:null,isOperaMobile:null,prefixedMatchesSelector:null,pEventTypes:null,wheelEvent:null};var w=x;b.default=w;var _={};function S(t){var e=t.parentNode;if(i.default.docFrag(e)){for(;(e=e.host)&&i.default.docFrag(e););return e}return e}function P(t,n){return e.window!==e.realWindow&&(n=n.replace(/\/deep\//g," ")),t[b.default.prefixedMatchesSelector](n)}Object.defineProperty(_,"__esModule",{value:!0}),_.nodeContains=function(t,e){if(t.contains)return t.contains(e);for(;e;){if(e===t)return!0;e=e.parentNode}return!1},_.closest=function(t,e){for(;i.default.element(t);){if(P(t,e))return t;t=S(t)}return null},_.parentNode=S,_.matchesSelector=P,_.indexOfDeepestElement=function(t){for(var n,r=[],o=0;o=m&&(n=o);else n=o}else n=o}var v,g,y,m;return n},_.matchesUpTo=function(t,e,n){for(;i.default.element(t);){if(P(t,e))return!0;if((t=S(t))===n)return P(t,e)}return!1},_.getActualElement=function(t){return t.correspondingUseElement||t},_.getScrollXY=T,_.getElementClientRect=M,_.getElementRect=function(t){var n=M(t);if(!b.default.isIOS7&&n){var r=T(e.getWindow(t));n.left+=r.x,n.right+=r.x,n.top+=r.y,n.bottom+=r.y}return n},_.getPath=function(t){var e=[];for(;t;)e.push(t),t=S(t);return e},_.trySelector=function(t){if(!i.default.string(t))return!1;return h.default.document.querySelector(t),!0};var O=function(t){return t.parentNode||t.host};function E(t,e){for(var n,r=[],o=t;(n=O(o))&&o!==e&&n!==o.ownerDocument;)r.unshift(o),o=n;return r}function T(t){return{x:(t=t||e.window).scrollX||t.document.documentElement.scrollLeft,y:t.scrollY||t.document.documentElement.scrollTop}}function M(t){var e=t instanceof h.default.SVGElement?t.getBoundingClientRect():t.getClientRects()[0];return e&&{left:e.left,right:e.right,top:e.top,bottom:e.bottom,width:e.width||e.right-e.left,height:e.height||e.bottom-e.top}}var j={};Object.defineProperty(j,"__esModule",{value:!0}),j.default=function(t,e){for(var n in e)t[n]=e[n];return t};var k={};function I(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n1?q(e):e[0];U(r,t.page),N(r,t.client),t.timeStamp=n},W.getTouchPair=V,W.pointerAverage=q,W.touchBBox=function(t){if(!t.length)return null;var e=V(t),n=Math.min(e[0].pageX,e[1].pageX),r=Math.min(e[0].pageY,e[1].pageY),o=Math.max(e[0].pageX,e[1].pageX),i=Math.max(e[0].pageY,e[1].pageY);return{x:n,y:r,left:n,top:r,right:o,bottom:i,width:o-n,height:i-r}},W.touchDistance=function(t,e){var n=e+"X",r=e+"Y",o=V(t),i=o[0][n]-o[1][n],a=o[0][r]-o[1][r];return(0,R.default)(i,a)},W.touchAngle=function(t,e){var n=e+"X",r=e+"Y",o=V(t),i=o[1][n]-o[0][n],a=o[1][r]-o[0][r];return 180*Math.atan2(a,i)/Math.PI},W.getPointerType=function(t){return i.default.string(t.pointerType)?t.pointerType:i.default.number(t.pointerType)?[void 0,void 0,"touch","pen","mouse"][t.pointerType]:/touch/.test(t.type)||t instanceof h.default.Touch?"touch":"mouse"},W.getEventTargets=function(t){var e=i.default.func(t.composedPath)?t.composedPath():t.path;return[_.getActualElement(e?e[0]:t.target),_.getActualElement(t.currentTarget)]},W.newCoords=function(){return{page:{x:0,y:0},client:{x:0,y:0},timeStamp:0}},W.coordsToEvent=function(t){return{coords:t,get page(){return this.coords.page},get client(){return this.coords.client},get timeStamp(){return this.coords.timeStamp},get pageX(){return this.coords.page.x},get pageY(){return this.coords.page.y},get clientX(){return this.coords.client.x},get clientY(){return this.coords.client.y},get pointerId(){return this.coords.pointerId},get target(){return this.coords.target},get type(){return this.coords.type},get pointerType(){return this.coords.pointerType},get buttons(){return this.coords.buttons},preventDefault:function(){}}},Object.defineProperty(W,"pointerExtend",{enumerable:!0,get:function(){return F.default}});var $={};function G(t,e){for(var n=0;ns.left&&f.xs.top&&f.y=s.left&&h<=s.right&&g>=s.top&&g<=s.bottom}if(v&&i.default.number(u)){var y=Math.max(0,Math.min(s.right,v.right)-Math.max(s.left,v.left))*Math.max(0,Math.min(s.bottom,v.bottom)-Math.max(s.top,v.top))/(v.width*v.height);l=y>=u}t.options.drop.checker&&(l=t.options.drop.checker(e,n,l,t,a,r,o));return l}(this,t,e,n,r,o,a)},n.dynamicDrop=function(e){return i.default.bool(e)?(t.dynamicDrop=e,n):t.dynamicDrop},(0,j.default)(e.phaselessTypes,{dragenter:!0,dragleave:!0,dropactivate:!0,dropdeactivate:!0,dropmove:!0,drop:!0}),e.methodDict.drop="dropzone",t.dynamicDrop=!1,o.actions.drop=vt.defaults},listeners:{"interactions:before-action-start":function(t){var e=t.interaction;"drag"===e.prepared.name&&(e.dropState={cur:{dropzone:null,element:null},prev:{dropzone:null,element:null},rejected:null,events:null,activeDrops:[]})},"interactions:after-action-start":function(t,e){var n=t.interaction,r=(t.event,t.iEvent);if("drag"===n.prepared.name){var o=n.dropState;o.activeDrops=null,o.events=null,o.activeDrops=ut(e,n.element),o.events=ft(n,0,r),o.events.activate&&(lt(o.activeDrops,o.events.activate),e.fire("actions/drop:start",{interaction:n,dragEvent:r}))}},"interactions:action-move":pt,"interactions:after-action-move":function(t,e){var n=t.interaction,r=t.iEvent;"drag"===n.prepared.name&&(dt(n,n.dropState.events),e.fire("actions/drop:move",{interaction:n,dragEvent:r}),n.dropState.events={})},"interactions:action-end":function(t,e){if("drag"===t.interaction.prepared.name){var n=t.interaction,r=t.iEvent;pt(t,e),dt(n,n.dropState.events),e.fire("actions/drop:end",{interaction:n,dragEvent:r})}},"interactions:stop":function(t){var e=t.interaction;if("drag"===e.prepared.name){var n=e.dropState;n&&(n.activeDrops=null,n.events=null,n.cur.dropzone=null,n.cur.element=null,n.prev.dropzone=null,n.prev.element=null,n.rejected=!1)}}},getActiveDrops:ut,getDrop:ct,getDropEvents:ft,fireDropEvents:dt,defaults:{enabled:!1,accept:null,overlap:"pointer"}},ht=vt;st.default=ht;var gt={};function yt(t){var e=t.interaction,n=t.iEvent,r=t.phase;if("gesture"===e.prepared.name){var o=e.pointers.map((function(t){return t.pointer})),a="start"===r,s="end"===r,l=e.interactable.options.deltaSource;if(n.touches=[o[0],o[1]],a)n.distance=W.touchDistance(o,l),n.box=W.touchBBox(o),n.scale=1,n.ds=0,n.angle=W.touchAngle(o,l),n.da=0,e.gesture.startDistance=n.distance,e.gesture.startAngle=n.angle;else if(s){var u=e.prevEvent;n.distance=u.distance,n.box=u.box,n.scale=u.scale,n.ds=0,n.angle=u.angle,n.da=0}else n.distance=W.touchDistance(o,l),n.box=W.touchBBox(o),n.scale=n.distance/e.gesture.startDistance,n.angle=W.touchAngle(o,l),n.ds=n.scale-e.gesture.scale,n.da=n.angle-e.gesture.angle;e.gesture.distance=n.distance,e.gesture.angle=n.angle,i.default.number(n.scale)&&n.scale!==1/0&&!isNaN(n.scale)&&(e.gesture.scale=n.scale)}}Object.defineProperty(gt,"__esModule",{value:!0}),gt.default=void 0;var mt={id:"actions/gesture",before:["actions/drag","actions/resize"],install:function(t){var e=t.actions,n=t.Interactable,r=t.defaults;n.prototype.gesturable=function(t){return i.default.object(t)?(this.options.gesture.enabled=!1!==t.enabled,this.setPerAction("gesture",t),this.setOnEvents("gesture",t),this):i.default.bool(t)?(this.options.gesture.enabled=t,this):this.options.gesture},e.map.gesture=mt,e.methodDict.gesture="gesturable",r.actions.gesture=mt.defaults},listeners:{"interactions:action-start":yt,"interactions:action-move":yt,"interactions:action-end":yt,"interactions:new":function(t){t.interaction.gesture={angle:0,distance:0,scale:1,startAngle:0,startDistance:0}},"auto-start:check":function(t){if(!(t.interaction.pointers.length<2)){var e=t.interactable.options.gesture;if(e&&e.enabled)return t.action={name:"gesture"},!1}}},defaults:{},getCursor:function(){return""}},bt=mt;gt.default=bt;var xt={};function wt(t,e,n,r,o,a,s){if(!e)return!1;if(!0===e){var l=i.default.number(a.width)?a.width:a.right-a.left,u=i.default.number(a.height)?a.height:a.bottom-a.top;if(s=Math.min(s,Math.abs(("left"===t||"right"===t?l:u)/2)),l<0&&("left"===t?t="right":"right"===t&&(t="left")),u<0&&("top"===t?t="bottom":"bottom"===t&&(t="top")),"left"===t)return n.x<(l>=0?a.left:a.right)+s;if("top"===t)return n.y<(u>=0?a.top:a.bottom)+s;if("right"===t)return n.x>(l>=0?a.right:a.left)-s;if("bottom"===t)return n.y>(u>=0?a.bottom:a.top)-s}return!!i.default.element(r)&&(i.default.element(e)?e===r:_.matchesUpTo(r,e,o))}function _t(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.resizeAxes){var r=e;n.interactable.options.resize.square?("y"===n.resizeAxes?r.delta.x=r.delta.y:r.delta.y=r.delta.x,r.axes="xy"):(r.axes=n.resizeAxes,"x"===n.resizeAxes?r.delta.y=0:"y"===n.resizeAxes&&(r.delta.x=0))}}Object.defineProperty(xt,"__esModule",{value:!0}),xt.default=void 0;var St={id:"actions/resize",before:["actions/drag"],install:function(t){var e=t.actions,n=t.browser,r=t.Interactable,o=t.defaults;St.cursors=function(t){return t.isIe9?{x:"e-resize",y:"s-resize",xy:"se-resize",top:"n-resize",left:"w-resize",bottom:"s-resize",right:"e-resize",topleft:"se-resize",bottomright:"se-resize",topright:"ne-resize",bottomleft:"ne-resize"}:{x:"ew-resize",y:"ns-resize",xy:"nwse-resize",top:"ns-resize",left:"ew-resize",bottom:"ns-resize",right:"ew-resize",topleft:"nwse-resize",bottomright:"nwse-resize",topright:"nesw-resize",bottomleft:"nesw-resize"}}(n),St.defaultMargin=n.supportsTouch||n.supportsPointerEvent?20:10,r.prototype.resizable=function(e){return function(t,e,n){if(i.default.object(e))return t.options.resize.enabled=!1!==e.enabled,t.setPerAction("resize",e),t.setOnEvents("resize",e),i.default.string(e.axis)&&/^x$|^y$|^xy$/.test(e.axis)?t.options.resize.axis=e.axis:null===e.axis&&(t.options.resize.axis=n.defaults.actions.resize.axis),i.default.bool(e.preserveAspectRatio)?t.options.resize.preserveAspectRatio=e.preserveAspectRatio:i.default.bool(e.square)&&(t.options.resize.square=e.square),t;if(i.default.bool(e))return t.options.resize.enabled=e,t;return t.options.resize}(this,e,t)},e.map.resize=St,e.methodDict.resize="resizable",o.actions.resize=St.defaults},listeners:{"interactions:new":function(t){t.interaction.resizeAxes="xy"},"interactions:action-start":function(t){!function(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.prepared.edges){var r=e,o=n.rect;n._rects={start:(0,j.default)({},o),corrected:(0,j.default)({},o),previous:(0,j.default)({},o),delta:{left:0,right:0,width:0,top:0,bottom:0,height:0}},r.edges=n.prepared.edges,r.rect=n._rects.corrected,r.deltaRect=n._rects.delta}}(t),_t(t)},"interactions:action-move":function(t){!function(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.prepared.edges){var r=e,o=n.interactable.options.resize.invert,i="reposition"===o||"negate"===o,a=n.rect,s=n._rects,l=s.start,u=s.corrected,c=s.delta,f=s.previous;if((0,j.default)(f,u),i){if((0,j.default)(u,a),"reposition"===o){if(u.top>u.bottom){var d=u.top;u.top=u.bottom,u.bottom=d}if(u.left>u.right){var p=u.left;u.left=u.right,u.right=p}}}else u.top=Math.min(a.top,l.bottom),u.bottom=Math.max(a.bottom,l.top),u.left=Math.min(a.left,l.right),u.right=Math.max(a.right,l.left);for(var v in u.width=u.right-u.left,u.height=u.bottom-u.top,u)c[v]=u[v]-f[v];r.edges=n.prepared.edges,r.rect=u,r.deltaRect=c}}(t),_t(t)},"interactions:action-end":function(t){var e=t.iEvent,n=t.interaction;if("resize"===n.prepared.name&&n.prepared.edges){var r=e;r.edges=n.prepared.edges,r.rect=n._rects.corrected,r.deltaRect=n._rects.delta}},"auto-start:check":function(t){var e=t.interaction,n=t.interactable,r=t.element,o=t.rect,a=t.buttons;if(o){var s=(0,j.default)({},e.coords.cur.page),l=n.options.resize;if(l&&l.enabled&&(!e.pointerIsDown||!/mouse|pointer/.test(e.pointerType)||0!=(a&l.mouseButtons))){if(i.default.object(l.edges)){var u={left:!1,right:!1,top:!1,bottom:!1};for(var c in u)u[c]=wt(c,l.edges[c],s,e._latestPointer.eventTarget,r,o,l.margin||St.defaultMargin);u.left=u.left&&!u.right,u.top=u.top&&!u.bottom,(u.left||u.right||u.top||u.bottom)&&(t.action={name:"resize",edges:u})}else{var f="y"!==l.axis&&s.x>o.right-St.defaultMargin,d="x"!==l.axis&&s.y>o.bottom-St.defaultMargin;(f||d)&&(t.action={name:"resize",axes:(f?"x":"")+(d?"y":"")})}return!t.action&&void 0}}}},defaults:{square:!1,preserveAspectRatio:!1,axis:"xy",margin:NaN,edges:null,invert:"none"},cursors:null,getCursor:function(t){var e=t.edges,n=t.axis,r=t.name,o=St.cursors,i=null;if(n)i=o[r+n];else if(e){for(var a="",s=["top","bottom","left","right"],l=0;l=1){var c={x:zt.x*u,y:zt.y*u};if(c.x||c.y){var f=Rt(a);i.default.window(a)?a.scrollBy(c.x,c.y):a&&(a.scrollLeft+=c.x,a.scrollTop+=c.y);var d=Rt(a),p={x:d.x-f.x,y:d.y-f.y};(p.x||p.y)&&e.fire({type:"autoscroll",target:n,interactable:e,delta:p,interaction:t,container:a})}zt.prevTime=s}zt.isScrolling&&(Mt.default.cancel(zt.i),zt.i=Mt.default.request(zt.scroll))},check:function(t,e){var n=t.options;return n[e].autoScroll&&n[e].autoScroll.enabled},onInteractionMove:function(t){var e=t.interaction,n=t.pointer;if(e.interacting()&&zt.check(e.interactable,e.prepared.name))if(e.simulation)zt.x=zt.y=0;else{var r,o,a,s,l=e.interactable,u=e.element,c=e.prepared.name,f=l.options[c].autoScroll,d=Ct(f.container,l,u);if(i.default.window(d))s=n.clientXd.innerWidth-zt.margin,a=n.clientY>d.innerHeight-zt.margin;else{var p=_.getElementClientRect(d);s=n.clientXp.right-zt.margin,a=n.clientY>p.bottom-zt.margin}zt.x=o?1:s?-1:0,zt.y=a?1:r?-1:0,zt.isScrolling||(zt.margin=f.margin,zt.speed=f.speed,zt.start(e))}}};function Ct(t,n,r){return(i.default.string(t)?(0,k.getStringOptionResult)(t,n,r):t)||(0,e.getWindow)(r)}function Rt(t){return i.default.window(t)&&(t=window.document.body),{x:t.scrollLeft,y:t.scrollTop}}var Ft={id:"auto-scroll",install:function(t){var e=t.defaults,n=t.actions;t.autoScroll=zt,zt.now=function(){return t.now()},n.phaselessTypes.autoscroll=!0,e.perAction.autoScroll=zt.defaults},listeners:{"interactions:new":function(t){t.interaction.autoScroll=null},"interactions:destroy":function(t){t.interaction.autoScroll=null,zt.stop(),zt.interaction&&(zt.interaction=null)},"interactions:stop":zt.stop,"interactions:action-move":function(t){return zt.onInteractionMove(t)}}};At.default=Ft;var Xt={};Object.defineProperty(Xt,"__esModule",{value:!0}),Xt.warnOnce=function(t,n){var r=!1;return function(){return r||(e.window.console.warn(n),r=!0),t.apply(this,arguments)}},Xt.copyAction=function(t,e){return t.name=e.name,t.axis=e.axis,t.edges=e.edges,t};var Yt={};function Wt(t){return i.default.bool(t)?(this.options.styleCursor=t,this):null===t?(delete this.options.styleCursor,this):this.options.styleCursor}function Lt(t){return i.default.func(t)?(this.options.actionChecker=t,this):null===t?(delete this.options.actionChecker,this):this.options.actionChecker}Object.defineProperty(Yt,"__esModule",{value:!0}),Yt.default=void 0;var Bt={id:"auto-start/interactableMethods",install:function(t){var e=t.Interactable;e.prototype.getAction=function(e,n,r,o){var i=function(t,e,n,r,o){var i=t.getRect(r),a=e.buttons||{0:1,1:4,3:8,4:16}[e.button],s={action:null,interactable:t,interaction:n,element:r,rect:i,buttons:a};return o.fire("auto-start:check",s),s.action}(this,n,r,o,t);return this.options.actionChecker?this.options.actionChecker(e,n,i,this,o,r):i},e.prototype.ignoreFrom=(0,Xt.warnOnce)((function(t){return this._backCompatOption("ignoreFrom",t)}),"Interactable.ignoreFrom() has been deprecated. Use Interactble.draggable({ignoreFrom: newValue})."),e.prototype.allowFrom=(0,Xt.warnOnce)((function(t){return this._backCompatOption("allowFrom",t)}),"Interactable.allowFrom() has been deprecated. Use Interactble.draggable({allowFrom: newValue})."),e.prototype.actionChecker=Lt,e.prototype.styleCursor=Wt}};Yt.default=Bt;var Ut={};function Nt(t,e,n,r,o){return e.testIgnoreAllow(e.options[t.name],n,r)&&e.options[t.name].enabled&&Gt(e,n,t,o)?t:null}function Vt(t,e,n,r,o,i,a){for(var s=0,l=r.length;s=s)return!1;if(d.interactable===t){if((u+=p===n.name?1:0)>=i)return!1;if(d.element===e&&(c++,p===n.name&&c>=a))return!1}}}return s>0}function Ht(t,e){return i.default.number(t)?(e.autoStart.maxInteractions=t,this):e.autoStart.maxInteractions}function Kt(t,e,n){var r=n.autoStart.cursorElement;r&&r!==t&&(r.style.cursor=""),t.ownerDocument.documentElement.style.cursor=e,t.style.cursor=e,n.autoStart.cursorElement=e?t:null}function Zt(t,e){var n=t.interactable,r=t.element,o=t.prepared;if("mouse"===t.pointerType&&n&&n.options.styleCursor){var a="";if(o.name){var s=n.options[o.name].cursorChecker;a=i.default.func(s)?s(o,n,r,t._interacting):e.actions.map[o.name].getCursor(o)}Kt(t.element,a||"",e)}else e.autoStart.cursorElement&&Kt(e.autoStart.cursorElement,"",e)}Object.defineProperty(Ut,"__esModule",{value:!0}),Ut.default=void 0;var Jt={id:"auto-start/base",before:["actions"],install:function(t){var e=t.interactStatic,n=t.defaults;t.usePlugin(Yt.default),n.base.actionChecker=null,n.base.styleCursor=!0,(0,j.default)(n.perAction,{manualStart:!1,max:1/0,maxPerElement:1,allowFrom:null,ignoreFrom:null,mouseButtons:1}),e.maxInteractions=function(e){return Ht(e,t)},t.autoStart={maxInteractions:1/0,withinInteractionLimit:Gt,cursorElement:null}},listeners:{"interactions:down":function(t,e){var n=t.interaction,r=t.pointer,o=t.event,i=t.eventTarget;n.interacting()||$t(n,qt(n,r,o,i,e),e)},"interactions:move":function(t,e){!function(t,e){var n=t.interaction,r=t.pointer,o=t.event,i=t.eventTarget;"mouse"!==n.pointerType||n.pointerIsDown||n.interacting()||$t(n,qt(n,r,o,i,e),e)}(t,e),function(t,e){var n=t.interaction;if(n.pointerIsDown&&!n.interacting()&&n.pointerWasMoved&&n.prepared.name){e.fire("autoStart:before-start",t);var r=n.interactable,o=n.prepared.name;o&&r&&(r.options[o].manualStart||!Gt(r,n.element,n.prepared,e)?n.stop():(n.start(n.prepared,r,n.element),Zt(n,e)))}}(t,e)},"interactions:stop":function(t,e){var n=t.interaction,r=n.interactable;r&&r.options.styleCursor&&Kt(n.element,"",e)}},maxInteractions:Ht,withinInteractionLimit:Gt,validateAction:Nt};Ut.default=Jt;var Qt={};Object.defineProperty(Qt,"__esModule",{value:!0}),Qt.default=void 0;var te={id:"auto-start/dragAxis",listeners:{"autoStart:before-start":function(t,e){var n=t.interaction,r=t.eventTarget,o=t.dx,a=t.dy;if("drag"===n.prepared.name){var s=Math.abs(o),l=Math.abs(a),u=n.interactable.options.drag,c=u.startAxis,f=s>l?"x":s0&&(e.autoStartHoldTimer=setTimeout((function(){e.start(e.prepared,e.interactable,e.element)}),n))},"interactions:move":function(t){var e=t.interaction,n=t.duplicate;e.autoStartHoldTimer&&e.pointerWasMoved&&!n&&(clearTimeout(e.autoStartHoldTimer),e.autoStartHoldTimer=null)},"autoStart:before-start":function(t){var e=t.interaction;ne(e)>0&&(e.prepared.name=null)}},getHoldDuration:ne};ee.default=re;var oe={};Object.defineProperty(oe,"__esModule",{value:!0}),oe.default=void 0;var ie={id:"auto-start",install:function(t){t.usePlugin(Ut.default),t.usePlugin(ee.default),t.usePlugin(Qt.default)}};oe.default=ie;var ae={};Object.defineProperty(ae,"__esModule",{value:!0}),ae.default=void 0;ae.default={};var se={};function le(t){return/^(always|never|auto)$/.test(t)?(this.options.preventDefault=t,this):i.default.bool(t)?(this.options.preventDefault=t?"always":"never",this):this.options.preventDefault}function ue(t){var e=t.interaction,n=t.event;e.interactable&&e.interactable.checkAndPreventDefault(n)}function ce(t){var n=t.Interactable;n.prototype.preventDefault=le,n.prototype.checkAndPreventDefault=function(n){return function(t,n,r){var o=t.options.preventDefault;if("never"!==o)if("always"!==o){if(n.events.supportsPassive&&/^touch(start|move)$/.test(r.type)){var a=(0,e.getWindow)(r.target).document,s=n.getDocOptions(a);if(!s||!s.events||!1!==s.events.passive)return}/^(mouse|pointer|touch)*(down|start)/i.test(r.type)||i.default.element(r.target)&&(0,_.matchesSelector)(r.target,"input,select,textarea,[contenteditable=true],[contenteditable=true] *")||r.preventDefault()}else r.preventDefault()}(this,t,n)},t.interactions.docEvents.push({type:"dragstart",listener:function(e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);n1&&void 0!==arguments[1]?arguments[1]:{},n=e.logger,r=t.Interactable,o=t.defaults;t.logger=n||console,o.base.devTools={ignore:{}},r.prototype.devTools=function(t){return t?((0,j.default)(this.options.devTools,t),this):this.options.devTools}},listeners:{"interactions:action-start":function(t,e){for(var n=t.interaction,r=0;rt.length)&&(e=t.length);for(var n=0,r=Array(e);n150)return null;var e=180*Math.atan2(t.prevEvent.velocityY,t.prevEvent.velocityX)/Math.PI;e<0&&(e+=360);var n=112.5<=e&&e<247.5,r=202.5<=e&&e<337.5;return{up:r,down:!r&&22.5<=e&&e<157.5,left:n,right:!n&&(292.5<=e||e<67.5),angle:e,speed:t.prevEvent.speed,velocity:{x:t.prevEvent.velocityX,y:t.prevEvent.velocityY}}}},{key:"preventDefault",value:function(){}},{key:"stopImmediatePropagation",value:function(){this.immediatePropagationStopped=this.propagationStopped=!0}},{key:"stopPropagation",value:function(){this.propagationStopped=!0}}])&&Re(e.prototype,n),r&&Re(e,r),i}($.BaseEvent);ze.InteractEvent=Be,Object.defineProperties(Be.prototype,{pageX:{get:function(){return this.page.x},set:function(t){this.page.x=t}},pageY:{get:function(){return this.page.y},set:function(t){this.page.y=t}},clientX:{get:function(){return this.client.x},set:function(t){this.client.x=t}},clientY:{get:function(){return this.client.y},set:function(t){this.client.y=t}},dx:{get:function(){return this.delta.x},set:function(t){this.delta.x=t}},dy:{get:function(){return this.delta.y},set:function(t){this.delta.y=t}},velocityX:{get:function(){return this.velocity.x},set:function(t){this.velocity.x=t}},velocityY:{get:function(){return this.velocity.y},set:function(t){this.velocity.y=t}}});var Ue={};Object.defineProperty(Ue,"__esModule",{value:!0}),Ue.PointerInfo=void 0;Ue.PointerInfo=function t(e,n,r,o,i){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.id=void 0,this.pointer=void 0,this.event=void 0,this.downTime=void 0,this.downTarget=void 0,this.id=e,this.pointer=n,this.event=r,this.downTime=o,this.downTarget=i};var Ne,Ve,qe={};function $e(t,e){for(var n=0;nthis.pointerMoveTolerance);var a=this.getPointerIndex(t),s={pointer:t,pointerIndex:a,pointerInfo:this.pointers[a],event:e,type:"move",eventTarget:n,dx:r,dy:o,duplicate:i,interaction:this};i||W.setCoordVelocity(this.coords.velocity,this.coords.delta),this._scopeFire("interactions:move",s),i||this.simulation||(this.interacting()&&(s.type=null,this.move(s)),this.pointerWasMoved&&W.copyCoords(this.coords.prev,this.coords.cur))}},{key:"move",value:function(t){t&&t.event||W.setZeroCoords(this.coords.delta),(t=(0,j.default)({pointer:this._latestPointer.pointer,event:this._latestPointer.event,eventTarget:this._latestPointer.eventTarget,interaction:this},t||{})).phase="move",this._doPhase(t)}},{key:"pointerUp",value:function(t,e,n,r){var o=this.getPointerIndex(t);-1===o&&(o=this.updatePointer(t,e,n,!1));var i=/cancel$/i.test(e.type)?"cancel":"up";this._scopeFire("interactions:".concat(i),{pointer:t,pointerIndex:o,pointerInfo:this.pointers[o],event:e,eventTarget:n,type:i,curEventTarget:r,interaction:this}),this.simulation||this.end(e),this.removePointer(t,e)}},{key:"documentBlur",value:function(t){this.end(t),this._scopeFire("interactions:blur",{event:t,type:"blur",interaction:this})}},{key:"end",value:function(t){var e;this._ending=!0,t=t||this._latestPointer.event,this.interacting()&&(e=this._doPhase({event:t,interaction:this,phase:"end"})),this._ending=!1,!0===e&&this.stop()}},{key:"currentAction",value:function(){return this._interacting?this.prepared.name:null}},{key:"interacting",value:function(){return this._interacting}},{key:"stop",value:function(){this._scopeFire("interactions:stop",{interaction:this}),this.interactable=this.element=null,this._interacting=!1,this._stopped=!0,this.prepared.name=this.prevEvent=null}},{key:"getPointerIndex",value:function(t){var e=W.getPointerId(t);return"mouse"===this.pointerType||"pen"===this.pointerType?this.pointers.length-1:K.findIndex(this.pointers,(function(t){return t.id===e}))}},{key:"getPointerInfo",value:function(t){return this.pointers[this.getPointerIndex(t)]}},{key:"updatePointer",value:function(t,e,n,r){var o=W.getPointerId(t),i=this.getPointerIndex(t),a=this.pointers[i];return r=!1!==r&&(r||/(down|start)$/i.test(e.type)),a?a.pointer=t:(a=new Ue.PointerInfo(o,t,e,null,null),i=this.pointers.length,this.pointers.push(a)),W.setCoords(this.coords.cur,this.pointers.map((function(t){return t.pointer})),this._now()),W.setCoordDeltas(this.coords.delta,this.coords.prev,this.coords.cur),r&&(this.pointerIsDown=!0,a.downTime=this.coords.cur.timeStamp,a.downTarget=n,W.pointerExtend(this.downPointer,t),this.interacting()||(W.copyCoords(this.coords.start,this.coords.cur),W.copyCoords(this.coords.prev,this.coords.cur),this.downEvent=e,this.pointerWasMoved=!1)),this._updateLatestPointer(t,e,n),this._scopeFire("interactions:update-pointer",{pointer:t,event:e,eventTarget:n,down:r,pointerInfo:a,pointerIndex:i,interaction:this}),i}},{key:"removePointer",value:function(t,e){var n=this.getPointerIndex(t);if(-1!==n){var r=this.pointers[n];this._scopeFire("interactions:remove-pointer",{pointer:t,event:e,eventTarget:null,pointerIndex:n,pointerInfo:r,interaction:this}),this.pointers.splice(n,1),this.pointerIsDown=!1}}},{key:"_updateLatestPointer",value:function(t,e,n){this._latestPointer.pointer=t,this._latestPointer.event=e,this._latestPointer.eventTarget=n}},{key:"destroy",value:function(){this._latestPointer.pointer=null,this._latestPointer.event=null,this._latestPointer.eventTarget=null}},{key:"_createPreparedEvent",value:function(t,e,n,r){return new ze.InteractEvent(this,t,this.prepared.name,e,this.element,n,r)}},{key:"_fireEvent",value:function(t){this.interactable.fire(t),(!this.prevEvent||t.timeStamp>=this.prevEvent.timeStamp)&&(this.prevEvent=t)}},{key:"_doPhase",value:function(t){var e=t.event,n=t.phase,r=t.preEnd,o=t.type,i=this.rect;if(i&&"move"===n&&(k.addEdges(this.edges,i,this.coords.delta[this.interactable.options.deltaSource]),i.width=i.right-i.left,i.height=i.bottom-i.top),!1===this._scopeFire("interactions:before-action-".concat(n),t))return!1;var a=t.iEvent=this._createPreparedEvent(e,n,r,o);return this._scopeFire("interactions:action-".concat(n),t),"start"===n&&(this.prevEvent=a),this._fireEvent(a),this._scopeFire("interactions:after-action-".concat(n),t),!0}},{key:"_now",value:function(){return Date.now()}}]),t}();qe.Interaction=Ke;var Ze=Ke;qe.default=Ze;var Je={};function Qe(t){t.pointerIsDown&&(rn(t.coords.cur,t.offset.total),t.offset.pending.x=0,t.offset.pending.y=0)}function tn(t){en(t.interaction)}function en(t){if(!function(t){return!(!t.offset.pending.x&&!t.offset.pending.y)}(t))return!1;var e=t.offset.pending;return rn(t.coords.cur,e),rn(t.coords.delta,e),k.addEdges(t.edges,t.rect,e),e.x=0,e.y=0,!0}function nn(t){var e=t.x,n=t.y;this.offset.pending.x+=e,this.offset.pending.y+=n,this.offset.total.x+=e,this.offset.total.y+=n}function rn(t,e){var n=t.page,r=t.client,o=e.x,i=e.y;n.x+=o,n.y+=i,r.x+=o,r.y+=i}Object.defineProperty(Je,"__esModule",{value:!0}),Je.addTotal=Qe,Je.applyPending=en,Je.default=void 0,qe._ProxyMethods.offsetBy="";var on={id:"offset",before:["modifiers","pointer-events","actions","inertia"],install:function(t){t.Interaction.prototype.offsetBy=nn},listeners:{"interactions:new":function(t){t.interaction.offset={total:{x:0,y:0},pending:{x:0,y:0}}},"interactions:update-pointer":function(t){return Qe(t.interaction)},"interactions:before-action-start":tn,"interactions:before-action-move":tn,"interactions:before-action-end":function(t){var e=t.interaction;if(en(e))return e.move({offset:!0}),e.end(),!1},"interactions:stop":function(t){var e=t.interaction;e.offset.total.x=0,e.offset.total.y=0,e.offset.pending.x=0,e.offset.pending.y=0}}};Je.default=on;var an={};function sn(t,e){for(var n=0;nn.minSpeed&&o>n.endSpeed)this.startInertia();else{if(i.result=i.setAll(this.modifierArg),!i.result.changed)return!1;this.startSmoothEnd()}return e.modification.result.rect=null,e.offsetBy(this.targetOffset),e._doPhase({interaction:e,event:t,phase:"inertiastart"}),e.offsetBy({x:-this.targetOffset.x,y:-this.targetOffset.y}),e.modification.result.rect=null,this.active=!0,e.simulation=this,!0}},{key:"startInertia",value:function(){var t=this,e=this.interaction.coords.velocity.client,n=un(this.interaction),r=n.resistance,o=-Math.log(n.endSpeed/this.v0)/r;this.targetOffset={x:(e.x-o)/r,y:(e.y-o)/r},this.te=o,this.lambda_v0=r/this.v0,this.one_ve_v0=1-n.endSpeed/this.v0;var i=this.modification,a=this.modifierArg;a.pageCoords={x:this.startCoords.x+this.targetOffset.x,y:this.startCoords.y+this.targetOffset.y},i.result=i.setAll(a),i.result.changed&&(this.isModified=!0,this.modifiedOffset={x:this.targetOffset.x+i.result.delta.x,y:this.targetOffset.y+i.result.delta.y}),this.onNextFrame((function(){return t.inertiaTick()}))}},{key:"startSmoothEnd",value:function(){var t=this;this.smoothEnd=!0,this.isModified=!0,this.targetOffset={x:this.modification.result.delta.x,y:this.modification.result.delta.y},this.onNextFrame((function(){return t.smoothEndTick()}))}},{key:"onNextFrame",value:function(t){var e=this;this.timeout=Mt.default.request((function(){e.active&&t()}))}},{key:"inertiaTick",value:function(){var t,e,n,r,o,i,a,s=this,l=this.interaction,u=un(l).resistance,c=(l._now()-this.t0)/1e3;if(c=0;n--){var r=e[n],o=r.selector,a=r.context,s=r.listeners;o===this.target&&a===this._context&&e.splice(n,1);for(var l=s.length-1;l>=0;l--)this._scopeEvents.removeDelegate(this.target,this._context,t,s[l][0],s[l][1])}else this._scopeEvents.remove(this.target,"all")}}]),t}();mn.Interactable=wn;var _n={};function Sn(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);n=0;a--){var p=f[a];if(p.selector===t&&p.context===e){for(var v=p.listeners,h=v.length-1;h>=0;h--){var g=Tn(v[h],2),y=g[0],m=g[1],b=m.capture,x=m.passive;if(y===o&&b===c.capture&&x===c.passive){v.splice(h,1),v.length||(f.splice(a,1),s(e,r,l),s(e,r,u,!0)),d=!0;break}}if(d)break}}},delegateListener:l,delegateUseCapture:u,delegatedEvents:n,documents:r,targets:e,supportsOptions:!1,supportsPassive:!1};function a(t,n,r,i){var a=kn(i),s=K.find(e,(function(e){return e.eventTarget===t}));s||(s={eventTarget:t,events:{}},e.push(s)),s.events[n]||(s.events[n]=[]),t.addEventListener&&!K.contains(s.events[n],r)&&(t.addEventListener(n,r,o.supportsOptions?a:a.capture),s.events[n].push(r))}function s(t,n,r,i){var a=kn(i),l=K.findIndex(e,(function(e){return e.eventTarget===t})),u=e[l];if(u&&u.events)if("all"!==n){var c=!1,f=u.events[n];if(f){if("all"===r){for(var d=f.length-1;d>=0;d--)s(t,n,f[d],a);return}for(var p=0;p=2)continue;if(!o.interacting()&&e===o.pointerType)return o}return null}};function Cn(t,e){return t.pointers.some((function(t){return t.id===e}))}var Rn=zn;An.default=Rn;var Fn={};function Xn(t){return(Xn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function Yn(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(t)))return;var n=[],r=!0,o=!1,i=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){o=!0,i=t}finally{try{r||null==s.return||s.return()}finally{if(o)throw i}}return n}(t,e)||function(t,e){if(!t)return;if("string"==typeof t)return Wn(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Wn(t,e)}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Wn(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n=0;r--){var o=e.interactions.list[r];o.interactable===n&&(o.stop(),e.fire("interactions:destroy",{interaction:o}),o.destroy(),e.interactions.list.length>2&&e.interactions.list.splice(r,1))}}},onDocSignal:Kn,doOnInteractions:Gn,methodNames:$n};Fn.default=Zn;var Jn={};function Qn(t){return(Qn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function tr(t,e,n){return(tr="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var r=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=or(t)););return t}(t,e);if(r){var o=Object.getOwnPropertyDescriptor(r,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}function er(t,e){return(er=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function nr(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=or(t);if(e){var o=or(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return rr(this,n)}}function rr(t,e){return!e||"object"!==Qn(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function or(t){return(or=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function ir(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function ar(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);nMath.abs(l.y),s.coords,s.rect),(0,j.default)(r,s.coords));return s.eventProps},defaults:{ratio:"preserve",equalDelta:!1,modifiers:[],enabled:!1}};function jr(t,e,n){var r=t.startCoords,o=t.edgeSign;e?n.y=r.y+(n.x-r.x)*o:n.x=r.x+(n.y-r.y)*o}function kr(t,e,n,r){var o=t.startRect,i=t.startCoords,a=t.ratio,s=t.edgeSign;if(e){var l=r.width/a;n.y=i.y+(l-o.height)*s}else{var u=r.height*a;n.x=i.x+(u-o.width)*s}}Pr.aspectRatio=Mr;var Ir=(0,ke.makeModifier)(Mr,"aspectRatio");Pr.default=Ir;var Dr={};Object.defineProperty(Dr,"__esModule",{value:!0}),Dr.default=void 0;var Ar=function(){};Ar._defaults={};var zr=Ar;Dr.default=zr;var Cr={};Object.defineProperty(Cr,"__esModule",{value:!0}),Object.defineProperty(Cr,"default",{enumerable:!0,get:function(){return Dr.default}});var Rr={};function Fr(t,e,n){return i.default.func(t)?k.resolveRectLike(t,e.interactable,e.element,[n.x,n.y,e]):k.resolveRectLike(t,e.interactable,e.element)}Object.defineProperty(Rr,"__esModule",{value:!0}),Rr.getRestrictionRect=Fr,Rr.restrict=Rr.default=void 0;var Xr={start:function(t){var e=t.rect,n=t.startOffset,r=t.state,o=t.interaction,i=t.pageCoords,a=r.options,s=a.elementRect,l=(0,j.default)({left:0,top:0,right:0,bottom:0},a.offset||{});if(e&&s){var u=Fr(a.restriction,o,i);if(u){var c=u.right-u.left-e.width,f=u.bottom-u.top-e.height;c<0&&(l.left+=c,l.right+=c),f<0&&(l.top+=f,l.bottom+=f)}l.left+=n.left-e.width*s.left,l.top+=n.top-e.height*s.top,l.right+=n.right-e.width*(1-s.right),l.bottom+=n.bottom-e.height*(1-s.bottom)}r.offset=l},set:function(t){var e=t.coords,n=t.interaction,r=t.state,o=r.options,i=r.offset,a=Fr(o.restriction,n,e);if(a){var s=k.xywhToTlbr(a);e.x=Math.max(Math.min(s.right-i.right,e.x),s.left+i.left),e.y=Math.max(Math.min(s.bottom-i.bottom,e.y),s.top+i.top)}},defaults:{restriction:null,elementRect:null,offset:null,endOnly:!1,enabled:!1}};Rr.restrict=Xr;var Yr=(0,ke.makeModifier)(Xr,"restrict");Rr.default=Yr;var Wr={};Object.defineProperty(Wr,"__esModule",{value:!0}),Wr.restrictEdges=Wr.default=void 0;var Lr={top:1/0,left:1/0,bottom:-1/0,right:-1/0},Br={top:-1/0,left:-1/0,bottom:1/0,right:1/0};function Ur(t,e){for(var n=["top","left","bottom","right"],r=0;rt.length)&&(e=t.length);for(var n=0,r=Array(e);n+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0,loaded_state:!1,restore_focus:!0,keyboard:{"ctrl-space":function(b){b.type="click",a(b.currentTarget).trigger(b)},enter:function(b){b.type="click",a(b.currentTarget).trigger(b)},left:function(b){if(b.preventDefault(),this.is_open(b.currentTarget))this.close_node(b.currentTarget);else{var c=this.get_parent(b.currentTarget);c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus()}},up:function(a){a.preventDefault();var b=this.get_prev_dom(a.currentTarget);b&&b.length&&b.children(".jstree-anchor").focus()},right:function(b){if(b.preventDefault(),this.is_closed(b.currentTarget))this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()});else if(this.is_open(b.currentTarget)){var c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0];c&&a(this._firstChild(c)).children(".jstree-anchor").focus()}},down:function(a){a.preventDefault();var b=this.get_next_dom(a.currentTarget);b&&b.length&&b.children(".jstree-anchor").focus()},"*":function(a){this.open_all()},home:function(b){b.preventDefault();var c=this._firstChild(this.get_container_ul()[0]);c&&a(c).children(".jstree-anchor").filter(":visible").focus()},end:function(a){a.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus()},f2:function(a){a.preventDefault(),this.edit(a.currentTarget)}}},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().outerHeight()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this.trigger("destroy"),this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},_create_prototype_node:function(){var a=i.createElement("LI"),b,c;return a.setAttribute("role","presentation"),b=i.createElement("I"),b.className="jstree-icon jstree-ocl",b.setAttribute("role","presentation"),a.appendChild(b),b=i.createElement("A"),b.className="jstree-anchor",b.setAttribute("href","#"),b.setAttribute("tabindex","-1"),b.setAttribute("role","treeitem"),c=i.createElement("I"),c.className="jstree-icon jstree-themeicon",c.setAttribute("role","presentation"),b.appendChild(c),a.appendChild(b),b=c=null,a},_kbevent_to_func:function(a){var b={8:"Backspace",9:"Tab",13:"Enter",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock",16:"Shift",17:"Ctrl",18:"Alt",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*",173:"-"},c=[];if(a.ctrlKey&&c.push("ctrl"),a.altKey&&c.push("alt"),a.shiftKey&&c.push("shift"),c.push(b[a.which]||a.which),c=c.sort().join("-").toLowerCase(),"shift-shift"===c||"ctrl-ctrl"===c||"alt-alt"===c)return null;var d=this.settings.core.keyboard,e,f;for(e in d)if(d.hasOwnProperty(e)&&(f=e,"-"!==f&&"+"!==f&&(f=f.replace("--","-MINUS").replace("+-","-MINUS").replace("++","-PLUS").replace("-+","-PLUS"),f=f.split(/-|\+/).sort().join("-").replace("MINUS","-").replace("PLUS","+").toLowerCase()),f===c))return d[e];return null},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;this._data.core.rtl&&(37===a.which?a.which=39:39===a.which&&(a.which=37));var b=this._kbevent_to_func(a);if(b){var c=b.call(this,a);if(c===!1||c===!0)return c}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this._data.core.themes.ellipsis=a.ellipsis,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"](),this[this._data.core.themes.ellipsis?"show_ellipsis":"hide_ellipsis"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").trigger("mouseleave"),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).trigger("mouseleave"),a(b.currentTarget).trigger("mouseenter"),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused&&this.settings.core.restore_focus){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(b){var c=this.settings.core.strings;return a.isFunction(c)?c.call(this,b):c&&c[b]?c[b]:b},_firstChild:function(a){a=a?a.firstChild:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_nextSibling:function(a){a=a?a.nextSibling:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_previousSibling:function(a){a=a?a.previousSibling:null;while(null!==a&&1!==a.nodeType)a=a.previousSibling;return a},get_node:function(b,c){b&&b.id&&(b=b.id),b instanceof a&&b.length&&b[0].id&&(b=b[0].id);var d;try{if(this._model.data[b])b=this._model.data[b];else if("string"==typeof b&&this._model.data[b.replace(/^#/,"")])b=this._model.data[b.replace(/^#/,"")];else if("string"==typeof b&&(d=a("#"+b.replace(a.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else if((d=this.element.find(b)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else{if(!(d=this.element.find(b)).length||!d.hasClass("jstree"))return!1;b=this._model.data[a.jstree.root]}return c&&(b=b.id===a.jstree.root?this.element:a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)),b}catch(e){return!1}},get_path:function(b,c,d){if(b=b.parents?b:this.get_node(b),!b||b.id===a.jstree.root||!b.parents)return!1;var e,f,g=[];for(g.push(d?b.id:b.text),e=0,f=b.parents.length;f>e;e++)g.push(d?b.parents[e]:this.get_text(b.parents[e]));return g=g.reverse().slice(1),c?g.join(c):g},get_next_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this._firstChild(this.get_container_ul()[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}if(b.hasClass("jstree-open")){d=this._firstChild(b.children(".jstree-children")[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);if(null!==d)return a(d)}d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return null!==d?a(d):b.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first()},get_prev_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this.get_container_ul()[0].lastChild;while(d&&0===d.offsetHeight)d=this._previousSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);if(null!==d){b=a(d);while(b.hasClass("jstree-open"))b=b.children(".jstree-children").first().children(".jstree-node:visible:last");return b}return d=b[0].parentNode.parentNode,d&&d.className&&-1!==d.className.indexOf("jstree-node")?a(d):!1},get_parent:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.parent:!1},get_children_dom:function(a){return a=this.get_node(a,!0),a[0]===this.element[0]?this.get_container_ul().children(".jstree-node"):a&&a.length?a.children(".jstree-children").children(".jstree-node"):!1},is_parent:function(a){return a=this.get_node(a),a&&(a.state.loaded===!1||a.children.length>0)},is_loaded:function(a){return a=this.get_node(a),a&&a.state.loaded},is_loading:function(a){return a=this.get_node(a),a&&a.state&&a.state.loading},is_open:function(a){return a=this.get_node(a),a&&a.state.opened},is_closed:function(a){return a=this.get_node(a),a&&this.is_parent(a)&&!a.state.opened},is_leaf:function(a){return!this.is_parent(a)},load_node:function(b,c){var d,e,f,g,h;if(a.isArray(b))return this._load_nodes(b.slice(),c),!0;if(b=this.get_node(b),!b)return c&&c.call(this,b,!1),!1;if(b.state.loaded){for(b.state.loaded=!1,f=0,g=b.parents.length;g>f;f++)this._model.data[b.parents[f]].children_d=a.vakata.array_filter(this._model.data[b.parents[f]].children_d,function(c){return-1===a.inArray(c,b.children_d)});for(d=0,e=b.children_d.length;e>d;d++)this._model.data[b.children_d[d]].state.selected&&(h=!0),delete this._model.data[b.children_d[d]];h&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(c){return-1===a.inArray(c,b.children_d)})),b.children=[],b.children_d=[],h&&this.trigger("changed",{action:"load_node",node:b,selected:this._data.core.selected})}return b.state.failed=!1,b.state.loading=!0,this.get_node(b,!0).addClass("jstree-loading").attr("aria-busy",!0),this._load_node(b,a.proxy(function(a){b=this._model.data[b.id],b.state.loading=!1,b.state.loaded=a,b.state.failed=!b.state.loaded;var d=this.get_node(b,!0),e=0,f=0,g=this._model.data,h=!1;for(e=0,f=b.children.length;f>e;e++)if(g[b.children[e]]&&!g[b.children[e]].state.hidden){h=!0;break}b.state.loaded&&d&&d.length&&(d.removeClass("jstree-closed jstree-open jstree-leaf"),h?"#"!==b.id&&d.addClass(b.state.opened?"jstree-open":"jstree-closed"):d.addClass("jstree-leaf")),d.removeClass("jstree-loading").attr("aria-busy",!1),this.trigger("load_node",{node:b,status:a}),c&&c.call(this,b,a)},this)),!0},_load_nodes:function(a,b,c,d){var e=!0,f=function(){this._load_nodes(a,b,!0)},g=this._model.data,h,i,j=[];for(h=0,i=a.length;i>h;h++)g[a[h]]&&(!g[a[h]].state.loaded&&!g[a[h]].state.failed||!c&&d)&&(this.is_loading(a[h])||this.load_node(a[h],f),e=!1);if(e){for(h=0,i=a.length;i>h;h++)g[a[h]]&&g[a[h]].state.loaded&&j.push(a[h]);b&&!b.done&&(b.call(this,j),b.done=!0)}},load_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=[],e=this._model.data,f=e[b.id].children_d,g,h;for(b.state&&!b.state.loaded&&d.push(b.id),g=0,h=f.length;h>g;g++)e[f[g]]&&e[f[g]].state&&!e[f[g]].state.loaded&&d.push(f[g]);d.length?this._load_nodes(d,function(){this.load_all(b,c)}):(c&&c.call(this,b),this.trigger("load_all",{node:b}))},_load_node:function(b,c){var d=this.settings.core.data,e,f=function g(){return 3!==this.nodeType&&8!==this.nodeType};return d?a.isFunction(d)?d.call(this,b,a.proxy(function(d){d===!1?c.call(this,!1):this["string"==typeof d?"_append_html_data":"_append_json_data"](b,"string"==typeof d?a(a.parseHTML(d)).filter(f):d,function(a){c.call(this,a)})},this)):"object"==typeof d?d.url?(d=a.extend(!0,{},d),a.isFunction(d.url)&&(d.url=d.url.call(this,b)),a.isFunction(d.data)&&(d.data=d.data.call(this,b)),a.ajax(d).done(a.proxy(function(d,e,g){var h=g.getResponseHeader("Content-Type");return h&&-1!==h.indexOf("json")||"object"==typeof d?this._append_json_data(b,d,function(a){c.call(this,a)}):h&&-1!==h.indexOf("html")||"string"==typeof d?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:g})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))},this)).fail(a.proxy(function(a){this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:a})},c.call(this,!1),this.settings.core.error.call(this,this._data.core.last_error)},this))):(e=a.isArray(d)?a.extend(!0,[],d):a.isPlainObject(d)?a.extend(!0,{},d):d,b.id===a.jstree.root?this._append_json_data(b,e,function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_05",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))):"string"==typeof d?b.id===a.jstree.root?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_06",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1)):c.call(this,!1):b.id===a.jstree.root?this._append_html_data(b,this._data.core.original_container_html.clone(!0),function(a){c.call(this,a)}):c.call(this,!1)},_node_changed:function(b){b=this.get_node(b),b&&-1===a.inArray(b.id,this._model.changed)&&this._model.changed.push(b.id)},_append_html_data:function(b,c,d){b=this.get_node(b),b.children=[],b.children_d=[];var e=c.is("ul")?c.children():c,f=b.id,g=[],h=[],i=this._model.data,j=i[f],k=this._data.core.selected.length,l,m,n;for(e.each(a.proxy(function(b,c){l=this._parse_model_from_html(a(c),f,j.parents.concat()),l&&(g.push(l),h.push(l),i[l].children_d.length&&(h=h.concat(i[l].children_d)))},this)),j.children=g,j.children_d=h,m=0,n=j.parents.length;n>m;m++)i[j.parents[m]].children_d=i[j.parents[m]].children_d.concat(h);this.trigger("model",{nodes:h,parent:f}),f!==a.jstree.root?(this._node_changed(f),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==k&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)},_append_json_data:function(b,c,d,e){if(null!==this.element){b=this.get_node(b),b.children=[],b.children_d=[],c.d&&(c=c.d,"string"==typeof c&&(c=JSON.parse(c))),a.isArray(c)||(c=[c]);var f=null,g={df:this._model.default_state,dat:c,par:b.id,m:this._model.data,t_id:this._id,t_cnt:this._cnt,sel:this._data.core.selected},h=this,i=function(a,b){a.data&&(a=a.data);var c=a.dat,d=a.par,e=[],f=[],g=[],i=a.df,j=a.t_id,k=a.t_cnt,l=a.m,m=l[d],n=a.sel,o,p,q,r,s=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f,h,j,k,m={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in i)i.hasOwnProperty(f)&&(m.state[f]=i[f]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(m.icon=a.data.jstree.icon),(m.icon===b||null===m.icon||""===m.icon)&&(m.icon=!0),a&&a.data&&(m.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(m.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(m.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(m.li_attr[f]=a.li_attr[f]);if(m.li_attr.id||(m.li_attr.id=e),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(m.a_attr[f]=a.a_attr[f]);for(a&&a.children&&a.children===!0&&(m.state.loaded=!1,m.children=[],m.children_d=[]),l[m.id]=m,f=0,h=m.children.length;h>f;f++)j=s(l[m.children[f]],m.id,d),k=l[j],m.children_d.push(j),k.children_d.length&&(m.children_d=m.children_d.concat(k.children_d));return delete a.data,delete a.children,l[m.id].original=a,m.state.selected&&g.push(m.id),m.id},t=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,h,m,n,o;do e="j"+j+"_"+ ++k;while(l[e]);o={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in i)i.hasOwnProperty(f)&&(o.state[f]=i[f]);if(a&&a.id&&(o.id=a.id.toString()),a&&a.text&&(o.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(o.icon=a.data.jstree.icon),(o.icon===b||null===o.icon||""===o.icon)&&(o.icon=!0),a&&a.data&&(o.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(o.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(o.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(o.li_attr[f]=a.li_attr[f]);if(o.li_attr.id&&!o.id&&(o.id=o.li_attr.id.toString()),o.id||(o.id=e),o.li_attr.id||(o.li_attr.id=o.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(o.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,h=a.children.length;h>f;f++)m=t(a.children[f],o.id,d),n=l[m],o.children.push(m),n.children_d.length&&(o.children_d=o.children_d.concat(n.children_d));o.children_d=o.children_d.concat(o.children)}return a&&a.children&&a.children===!0&&(o.state.loaded=!1,o.children=[],o.children_d=[]),delete a.data,delete a.children,o.original=a,l[o.id]=o,o.state.selected&&g.push(o.id),o.id};if(c.length&&c[0].id!==b&&c[0].parent!==b){for(p=0,q=c.length;q>p;p++)c[p].children||(c[p].children=[]),c[p].state||(c[p].state={}),l[c[p].id.toString()]=c[p];for(p=0,q=c.length;q>p;p++)l[c[p].parent.toString()]?(l[c[p].parent.toString()].children.push(c[p].id.toString()),m.children_d.push(c[p].id.toString())):"undefined"!=typeof h&&(h._data.core.last_error={error:"parse",plugin:"core",id:"core_07",reason:"Node with invalid parent",data:JSON.stringify({id:c[p].id.toString(),parent:c[p].parent.toString()})},h.settings.core.error.call(h,h._data.core.last_error));for(p=0,q=m.children.length;q>p;p++)o=s(l[m.children[p]],d,m.parents.concat()),f.push(o),l[o].children_d.length&&(f=f.concat(l[o].children_d));for(p=0,q=m.parents.length;q>p;p++)l[m.parents[p]].children_d=l[m.parents[p]].children_d.concat(f);r={cnt:k,mod:l,sel:n,par:d,dpc:f,add:g}}else{for(p=0,q=c.length;q>p;p++)o=t(c[p],d,m.parents.concat()),o&&(e.push(o),f.push(o),l[o].children_d.length&&(f=f.concat(l[o].children_d)));for(m.children=e,m.children_d=f,p=0,q=m.parents.length;q>p;p++)l[m.parents[p]].children_d=l[m.parents[p]].children_d.concat(f);r={cnt:k,mod:l,sel:n,par:d,dpc:f,add:g}}return"undefined"!=typeof window&&"undefined"!=typeof window.document?r:void postMessage(r)},k=function(b,c){if(null!==this.element){this._cnt=b.cnt;var e,f=this._model.data;for(e in f)f.hasOwnProperty(e)&&f[e].state&&f[e].state.loading&&b.mod[e]&&(b.mod[e].state.loading=!0);if(this._model.data=b.mod,c){var g,i=b.add,k=b.sel,l=this._data.core.selected.slice();if(f=this._model.data,k.length!==l.length||a.vakata.array_unique(k.concat(l)).length!==k.length){for(e=0,g=k.length;g>e;e++)-1===a.inArray(k[e],i)&&-1===a.inArray(k[e],l)&&(f[k[e]].state.selected=!1);for(e=0,g=l.length;g>e;e++)-1===a.inArray(l[e],k)&&(f[l[e]].state.selected=!0)}}b.add.length&&(this._data.core.selected=this._data.core.selected.concat(b.add)),this.trigger("model",{nodes:b.dpc,parent:b.par}),b.par!==a.jstree.root?(this._node_changed(b.par),this.redraw()):this.redraw(!0),b.add.length&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),!c&&j?j(function(){d.call(h,!0)}):d.call(h,!0)}};if(this.settings.core.worker&&window.Blob&&window.URL&&window.Worker)try{null===this._wrk&&(this._wrk=window.URL.createObjectURL(new window.Blob(["self.onmessage = "+i.toString()],{type:"text/javascript"}))),!this._data.core.working||e?(this._data.core.working=!0,f=new window.Worker(this._wrk),f.onmessage=a.proxy(function(a){k.call(this,a.data,!0);try{f.terminate(),f=null}catch(b){}this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1},this),g.par?f.postMessage(g):this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1):this._data.core.worker_queue.push([b,c,d,!0])}catch(l){k.call(this,i(g),!1),this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1}else k.call(this,i(g),!1)}},_parse_model_from_html:function(c,d,e){e=e?[].concat(e):[],d&&e.unshift(d);var f,g,h=this._model.data,i={id:!1,text:!1,icon:!0,parent:d,parents:e,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},j,k,l;for(j in this._model.default_state)this._model.default_state.hasOwnProperty(j)&&(i.state[j]=this._model.default_state[j]);if(k=a.vakata.attributes(c,!0),a.each(k,function(b,c){return c=a.trim(c),c.length?(i.li_attr[b]=c,void("id"===b&&(i.id=c.toString()))):!0}),k=c.children("a").first(),k.length&&(k=a.vakata.attributes(k,!0),a.each(k,function(b,c){c=a.trim(c),c.length&&(i.a_attr[b]=c)})),k=c.children("a").first().length?c.children("a").first().clone():c.clone(),k.children("ins, i, ul").remove(),k=k.html(),k=a("
      ").html(k),i.text=this.settings.core.force_text?k.text():k.html(),k=c.data(),i.data=k?a.extend(!0,{},k):null,i.state.opened=c.hasClass("jstree-open"),i.state.selected=c.children("a").hasClass("jstree-clicked"),i.state.disabled=c.children("a").hasClass("jstree-disabled"),i.data&&i.data.jstree)for(j in i.data.jstree)i.data.jstree.hasOwnProperty(j)&&(i.state[j]=i.data.jstree[j]);k=c.children("a").children(".jstree-themeicon"),k.length&&(i.icon=k.hasClass("jstree-themeicon-hidden")?!1:k.attr("rel")),i.state.icon!==b&&(i.icon=i.state.icon),(i.icon===b||null===i.icon||""===i.icon)&&(i.icon=!0),k=c.children("ul").children("li");do l="j"+this._id+"_"+ ++this._cnt;while(h[l]);return i.id=i.li_attr.id?i.li_attr.id.toString():l,k.length?(k.each(a.proxy(function(b,c){f=this._parse_model_from_html(a(c),i.id,e),g=this._model.data[f],i.children.push(f),g.children_d.length&&(i.children_d=i.children_d.concat(g.children_d))},this)),i.children_d=i.children_d.concat(i.children)):c.hasClass("jstree-closed")&&(i.state.loaded=!1),i.li_attr["class"]&&(i.li_attr["class"]=i.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),i.a_attr["class"]&&(i.a_attr["class"]=i.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),h[i.id]=i,i.state.selected&&this._data.core.selected.push(i.id),i.id},_parse_model_from_flat_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f=this._model.data,g=this._model.default_state,h,i,j,k,l={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(h in g)g.hasOwnProperty(h)&&(l.state[h]=g[h]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(h in a.data.jstree)a.data.jstree.hasOwnProperty(h)&&(l.state[h]=a.data.jstree[h]);if(a&&"object"==typeof a.state)for(h in a.state)a.state.hasOwnProperty(h)&&(l.state[h]=a.state[h]);if(a&&"object"==typeof a.li_attr)for(h in a.li_attr)a.li_attr.hasOwnProperty(h)&&(l.li_attr[h]=a.li_attr[h]);if(l.li_attr.id||(l.li_attr.id=e),a&&"object"==typeof a.a_attr)for(h in a.a_attr)a.a_attr.hasOwnProperty(h)&&(l.a_attr[h]=a.a_attr[h]);for(a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),f[l.id]=l,h=0,i=l.children.length;i>h;h++)j=this._parse_model_from_flat_json(f[l.children[h]],l.id,d),k=f[j],l.children_d.push(j),k.children_d.length&&(l.children_d=l.children_d.concat(k.children_d));return delete a.data,delete a.children,f[l.id].original=a,l.state.selected&&this._data.core.selected.push(l.id),l.id},_parse_model_from_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,g,h,i,j=this._model.data,k=this._model.default_state,l;do e="j"+this._id+"_"+ ++this._cnt;while(j[e]);l={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in k)k.hasOwnProperty(f)&&(l.state[f]=k[f]);if(a&&a.id&&(l.id=a.id.toString()),a&&a.text&&(l.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(l.state[f]=a.data.jstree[f]); +if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(l.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(l.li_attr[f]=a.li_attr[f]);if(l.li_attr.id&&!l.id&&(l.id=l.li_attr.id.toString()),l.id||(l.id=e),l.li_attr.id||(l.li_attr.id=l.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(l.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,g=a.children.length;g>f;f++)h=this._parse_model_from_json(a.children[f],l.id,d),i=j[h],l.children.push(h),i.children_d.length&&(l.children_d=l.children_d.concat(i.children_d));l.children_d=l.children.concat(l.children_d)}return a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),delete a.data,delete a.children,l.original=a,j[l.id]=l,l.state.selected&&this._data.core.selected.push(l.id),l.id},_redraw:function(){var b=this._model.force_full_redraw?this._model.data[a.jstree.root].children.concat([]):this._model.changed.concat([]),c=i.createElement("UL"),d,e,f,g=this._data.core.focused;for(e=0,f=b.length;f>e;e++)d=this.redraw_node(b[e],!0,this._model.force_full_redraw),d&&this._model.force_full_redraw&&c.appendChild(d);this._model.force_full_redraw&&(c.className=this.get_container_ul()[0].className,c.setAttribute("role","group"),this.element.empty().append(c)),null!==g&&this.settings.core.restore_focus&&(d=this.get_node(g,!0),d&&d.length&&d.children(".jstree-anchor")[0]!==i.activeElement?d.children(".jstree-anchor").focus():this._data.core.focused=null),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:b})},redraw:function(a){a&&(this._model.force_full_redraw=!0),this._redraw()},draw_children:function(b){var c=this.get_node(b),d=!1,e=!1,f=!1,g=i;if(!c)return!1;if(c.id===a.jstree.root)return this.redraw(!0);if(b=this.get_node(b,!0),!b||!b.length)return!1;if(b.children(".jstree-children").remove(),b=b[0],c.children.length&&c.state.loaded){for(f=g.createElement("UL"),f.setAttribute("role","group"),f.className="jstree-children",d=0,e=c.children.length;e>d;d++)f.appendChild(this.redraw_node(c.children[d],!0,!0));b.appendChild(f)}},redraw_node:function(b,c,d,e){var f=this.get_node(b),g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n="",o=i,p=this._model.data,q=!1,r=!1,s=null,t=0,u=0,v=!1,w=!1;if(!f)return!1;if(f.id===a.jstree.root)return this.redraw(!0);if(c=c||0===f.children.length,b=i.querySelector?this.element[0].querySelector("#"+(-1!=="0123456789".indexOf(f.id[0])?"\\3"+f.id[0]+" "+f.id.substr(1).replace(a.jstree.idregex,"\\$&"):f.id.replace(a.jstree.idregex,"\\$&"))):i.getElementById(f.id))b=a(b),d||(g=b.parent().parent()[0],g===this.element[0]&&(g=null),h=b.index()),c||!f.children.length||b.children(".jstree-children").length||(c=!0),c||(j=b.children(".jstree-children")[0]),q=b.children(".jstree-anchor")[0]===i.activeElement,b.remove();else if(c=!0,!d){if(g=f.parent!==a.jstree.root?a("#"+f.parent.replace(a.jstree.idregex,"\\$&"),this.element)[0]:null,!(null===g||g&&p[f.parent].state.opened))return!1;h=a.inArray(f.id,null===g?p[a.jstree.root].children:p[f.parent].children)}b=this._data.core.node.cloneNode(!0),n="jstree-node ";for(k in f.li_attr)if(f.li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"!==k?b.setAttribute(k,f.li_attr[k]):n+=f.li_attr[k]}for(f.a_attr.id||(f.a_attr.id=f.id+"_anchor"),b.setAttribute("aria-selected",!!f.state.selected),b.childNodes[1].setAttribute("aria-selected",!!f.state.selected),b.setAttribute("aria-level",f.parents.length),b.childNodes[1].setAttribute("aria-level",f.parents.length),b.setAttribute("aria-labelledby",f.a_attr.id),f.state.disabled&&(b.setAttribute("aria-disabled",!0),b.childNodes[1].setAttribute("aria-disabled",!0)),k=0,l=f.children.length;l>k;k++)if(!p[f.children[k]].state.hidden){v=!0;break}if(null!==f.parent&&p[f.parent]&&!f.state.hidden&&(k=a.inArray(f.id,p[f.parent].children),w=f.id,-1!==k))for(k++,l=p[f.parent].children.length;l>k;k++)if(p[p[f.parent].children[k]].state.hidden||(w=p[f.parent].children[k]),w!==f.id)break;f.state.hidden&&(n+=" jstree-hidden"),f.state.loading&&(n+=" jstree-loading"),f.state.loaded&&!v?n+=" jstree-leaf":(n+=f.state.opened&&f.state.loaded?" jstree-open":" jstree-closed",b.setAttribute("aria-expanded",f.state.opened&&f.state.loaded),b.childNodes[1].setAttribute("aria-expanded",f.state.opened&&f.state.loaded)),w===f.id&&(n+=" jstree-last"),b.id=f.id,b.className=n,n=(f.state.selected?" jstree-clicked":"")+(f.state.disabled?" jstree-disabled":"");for(l in f.a_attr)if(f.a_attr.hasOwnProperty(l)){if("href"===l&&"#"===f.a_attr[l])continue;"class"!==l?b.childNodes[1].setAttribute(l,f.a_attr[l]):n+=" "+f.a_attr[l]}if(n.length&&(b.childNodes[1].className="jstree-anchor "+n),(f.icon&&f.icon!==!0||f.icon===!1)&&(f.icon===!1?b.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===f.icon.indexOf("/")&&-1===f.icon.indexOf(".")?b.childNodes[1].childNodes[0].className+=" "+f.icon+" jstree-themeicon-custom":(b.childNodes[1].childNodes[0].style.backgroundImage='url("'+f.icon+'")',b.childNodes[1].childNodes[0].style.backgroundPosition="center center",b.childNodes[1].childNodes[0].style.backgroundSize="auto",b.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),this.settings.core.force_text?b.childNodes[1].appendChild(o.createTextNode(f.text)):b.childNodes[1].innerHTML+=f.text,c&&f.children.length&&(f.state.opened||e)&&f.state.loaded){for(m=o.createElement("UL"),m.setAttribute("role","group"),m.className="jstree-children",k=0,l=f.children.length;l>k;k++)m.appendChild(this.redraw_node(f.children[k],c,!0));b.appendChild(m)}if(j&&b.appendChild(j),!d){for(g||(g=this.element[0]),k=0,l=g.childNodes.length;l>k;k++)if(g.childNodes[k]&&g.childNodes[k].className&&-1!==g.childNodes[k].className.indexOf("jstree-children")){s=g.childNodes[k];break}s||(s=o.createElement("UL"),s.setAttribute("role","group"),s.className="jstree-children",g.appendChild(s)),g=s,hf;f++)this.open_node(c[f],d,e);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(e=e===b?this.settings.core.animation:e,this.is_closed(c)?this.is_loaded(c)?(h=this.get_node(c,!0),i=this,h.length&&(e&&h.children(".jstree-children").length&&h.children(".jstree-children").stop(!0,!0),c.children.length&&!this._firstChild(h.children(".jstree-children")[0])&&this.draw_children(c),e?(this.trigger("before_open",{node:c}),h.children(".jstree-children").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children(".jstree-anchor").attr("aria-expanded",!0).end().children(".jstree-children").stop(!0,!0).slideDown(e,function(){this.style.display="",i.element&&i.trigger("after_open",{node:c})})):(this.trigger("before_open",{node:c}),h[0].className=h[0].className.replace("jstree-closed","jstree-open"),h[0].setAttribute("aria-expanded",!0),h[0].childNodes[1].setAttribute("aria-expanded",!0))),c.state.opened=!0,d&&d.call(this,c,!0),h.length||this.trigger("before_open",{node:c}),this.trigger("open_node",{node:c}),e&&h.length||this.trigger("after_open",{node:c}),!0):this.is_loading(c)?setTimeout(a.proxy(function(){this.open_node(c,d,e)},this),500):void this.load_node(c,function(a,b){return b?this.open_node(a,d,e):d?d.call(this,a,!1):!1}):(d&&d.call(this,c,!1),!1)):!1},_open_to:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c,d,e=b.parents;for(c=0,d=e.length;d>c;c+=1)c!==a.jstree.root&&this.open_node(e[c],!1,0);return a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)},close_node:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.close_node(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?this.is_closed(c)?!1:(d=d===b?this.settings.core.animation:d,g=this,h=this.get_node(c,!0),c.state.opened=!1,this.trigger("close_node",{node:c}),void(h.length?d?h.children(".jstree-children").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children(".jstree-anchor").attr("aria-expanded",!1).end().children(".jstree-children").stop(!0,!0).slideUp(d,function(){this.style.display="",h.children(".jstree-children").remove(),g.element&&g.trigger("after_close",{node:c})}):(h[0].className=h[0].className.replace("jstree-open","jstree-closed"),h.children(".jstree-anchor").attr("aria-expanded",!1),h.attr("aria-expanded",!1).children(".jstree-children").remove(),this.trigger("after_close",{node:c})):this.trigger("after_close",{node:c}))):!1},toggle_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.toggle_node(b[c]);return!0}return this.is_closed(b)?this.open_node(b):this.is_open(b)?this.close_node(b):void 0},open_all:function(b,c,d){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var e=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),f,g,h;if(!e.length){for(f=0,g=b.children_d.length;g>f;f++)this.is_closed(this._model.data[b.children_d[f]])&&(this._model.data[b.children_d[f]].state.opened=!0);return this.trigger("open_all",{node:b})}d=d||e,h=this,e=this.is_closed(b)?e.find(".jstree-closed").addBack():e.find(".jstree-closed"),e.each(function(){h.open_node(this,function(a,b){b&&this.is_parent(a)&&this.open_all(a,c,d)},c||0)}),0===d.find(".jstree-closed").length&&this.trigger("open_all",{node:this.get_node(d)})},close_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),e=this,f,g;for(d.length&&(d=this.is_open(b)?d.find(".jstree-open").addBack():d.find(".jstree-open"),a(d.get().reverse()).each(function(){e.close_node(this,c||0)})),f=0,g=b.children_d.length;g>f;f++)this._model.data[b.children_d[f]].state.opened=!1;this.trigger("close_all",{node:b})},is_disabled:function(a){return a=this.get_node(a),a&&a.state&&a.state.disabled},enable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!1,this.get_node(b,!0).children(".jstree-anchor").removeClass("jstree-disabled").attr("aria-disabled",!1),void this.trigger("enable_node",{node:b})):!1},disable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!0,this.get_node(b,!0).children(".jstree-anchor").addClass("jstree-disabled").attr("aria-disabled",!0),void this.trigger("disable_node",{node:b})):!1},is_hidden:function(a){return a=this.get_node(a),a.state.hidden===!0},hide_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.hide_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden||(b.state.hidden=!0,this._node_changed(b.parent),c||this.redraw(),this.trigger("hide_node",{node:b}))):!1},show_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.show_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden&&(b.state.hidden=!1,this._node_changed(b.parent),c||this.redraw(),this.trigger("show_node",{node:b}))):!1},hide_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&!d[c].state.hidden&&(d[c].state.hidden=!0,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("hide_all",{nodes:e}),e},show_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&d[c].state.hidden&&(d[c].state.hidden=!1,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("show_all",{nodes:e}),e},activate_node:function(a,c){if(this.is_disabled(a))return!1;if(c&&"object"==typeof c||(c={}),this._data.core.last_clicked=this._data.core.last_clicked&&this._data.core.last_clicked.id!==b?this.get_node(this._data.core.last_clicked.id):null,this._data.core.last_clicked&&!this._data.core.last_clicked.state.selected&&(this._data.core.last_clicked=null),!this._data.core.last_clicked&&this._data.core.selected.length&&(this._data.core.last_clicked=this.get_node(this._data.core.selected[this._data.core.selected.length-1])),this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&(!c.shiftKey||this._data.core.last_clicked&&this.get_parent(a)&&this.get_parent(a)===this._data.core.last_clicked.parent))if(c.shiftKey){var d=this.get_node(a).id,e=this._data.core.last_clicked.id,f=this.get_node(this._data.core.last_clicked.parent).children,g=!1,h,i;for(h=0,i=f.length;i>h;h+=1)f[h]===d&&(g=!g),f[h]===e&&(g=!g),this.is_disabled(f[h])||!g&&f[h]!==d&&f[h]!==e?this.deselect_node(f[h],!0,c):this.is_hidden(f[h])||this.select_node(f[h],!0,!1,c);this.trigger("changed",{action:"select_node",node:this.get_node(a),selected:this._data.core.selected,event:c})}else this.is_selected(a)?this.deselect_node(a,!1,c):this.select_node(a,!1,!1,c);else!this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&this.is_selected(a)?this.deselect_node(a,!1,c):(this.deselect_all(!0),this.select_node(a,!1,!1,c),this._data.core.last_clicked=this.get_node(a));this.trigger("activate_node",{node:this.get_node(a),event:c})},hover_node:function(a){if(a=this.get_node(a,!0),!a||!a.length||a.children(".jstree-hovered").length)return!1;var b=this.element.find(".jstree-hovered"),c=this.element;b&&b.length&&this.dehover_node(b),a.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(a)}),setTimeout(function(){c.attr("aria-activedescendant",a[0].id)},0)},dehover_node:function(a){return a=this.get_node(a,!0),a&&a.length&&a.children(".jstree-hovered").length?(a.children(".jstree-anchor").removeClass("jstree-hovered"),void this.trigger("dehover_node",{node:this.get_node(a)})):!1},select_node:function(b,c,d,e){var f,g,h,i;if(a.isArray(b)){for(b=b.slice(),g=0,h=b.length;h>g;g++)this.select_node(b[g],c,d,e);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.selected||(b.state.selected=!0,this._data.core.selected.push(b.id),d||(f=this._open_to(b)),f&&f.length&&f.attr("aria-selected",!0).children(".jstree-anchor").addClass("jstree-clicked").attr("aria-selected",!0),this.trigger("select_node",{node:b,selected:this._data.core.selected,event:e}),c||this.trigger("changed",{action:"select_node",node:b,selected:this._data.core.selected,event:e})))):!1},deselect_node:function(b,c,d){var e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.deselect_node(b[e],c,d);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(g=this.get_node(b,!0),void(b.state.selected&&(b.state.selected=!1,this._data.core.selected=a.vakata.array_remove_item(this._data.core.selected,b.id),g.length&&g.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-clicked").attr("aria-selected",!1),this.trigger("deselect_node",{node:b,selected:this._data.core.selected,event:d}),c||this.trigger("changed",{action:"deselect_node",node:b,selected:this._data.core.selected,event:d})))):!1},select_all:function(b){var c=this._data.core.selected.concat([]),d,e;for(this._data.core.selected=this._model.data[a.jstree.root].children_d.concat(),d=0,e=this._data.core.selected.length;e>d;d++)this._model.data[this._data.core.selected[d]]&&(this._model.data[this._data.core.selected[d]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),b||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:c})},deselect_all:function(a){var b=this._data.core.selected.concat([]),c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)this._model.data[this._data.core.selected[c]]&&(this._model.data[this._data.core.selected[c]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked").attr("aria-selected",!1).parent().attr("aria-selected",!1),this.trigger("deselect_all",{selected:this._data.core.selected,node:b}),a||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:b})},is_selected:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.selected:!1},get_selected:function(b){return b?a.map(this._data.core.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.core.selected.slice()},get_top_selected:function(b){var c=this.get_selected(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},get_bottom_selected:function(b){var c=this.get_selected(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},get_state:function(){var b={core:{open:[],loaded:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},c;for(c in this._model.data)this._model.data.hasOwnProperty(c)&&c!==a.jstree.root&&(this._model.data[c].state.loaded&&this.settings.core.loaded_state&&b.core.loaded.push(c),this._model.data[c].state.opened&&b.core.open.push(c),this._model.data[c].state.selected&&b.core.selected.push(c));return b},set_state:function(c,d){if(c){if(c.core&&c.core.selected&&c.core.initial_selection===b&&(c.core.initial_selection=this._data.core.selected.concat([]).sort().join(",")),c.core){var e,f,g,h,i;if(c.core.loaded)return this.settings.core.loaded_state&&a.isArray(c.core.loaded)&&c.core.loaded.length?this._load_nodes(c.core.loaded,function(a){delete c.core.loaded,this.set_state(c,d)}):(delete c.core.loaded,this.set_state(c,d)),!1;if(c.core.open)return a.isArray(c.core.open)&&c.core.open.length?this._load_nodes(c.core.open,function(a){this.open_node(a,!1,0),delete c.core.open,this.set_state(c,d)}):(delete c.core.open,this.set_state(c,d)),!1;if(c.core.scroll)return c.core.scroll&&c.core.scroll.left!==b&&this.element.scrollLeft(c.core.scroll.left),c.core.scroll&&c.core.scroll.top!==b&&this.element.scrollTop(c.core.scroll.top),delete c.core.scroll,this.set_state(c,d),!1;if(c.core.selected)return h=this,(c.core.initial_selection===b||c.core.initial_selection===this._data.core.selected.concat([]).sort().join(","))&&(this.deselect_all(),a.each(c.core.selected,function(a,b){h.select_node(b,!1,!0)})),delete c.core.initial_selection,delete c.core.selected,this.set_state(c,d),!1;for(i in c)c.hasOwnProperty(i)&&"core"!==i&&-1===a.inArray(i,this.settings.plugins)&&delete c[i];if(a.isEmptyObject(c.core))return delete c.core,this.set_state(c,d),!1}return a.isEmptyObject(c)?(c=null,d&&d.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(b,c){this._data.core.state=c===!0?{}:this.get_state(),c&&a.isFunction(c)&&(this._data.core.state=c.call(this,this._data.core.state)),this._cnt=0,this._model.data={},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this._data.core.selected=[],this._data.core.last_clicked=null,this._data.core.focused=null;var d=this.get_container_ul()[0].className;b||(this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(a.jstree.root,function(b,c){c&&(this.get_container_ul()[0].className=d,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(a.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c=[],d=[],e=this._data.core.selected.concat([]);d.push(b.id),b.state.opened===!0&&c.push(b.id),this.get_node(b,!0).find(".jstree-open").each(function(){d.push(this.id),c.push(this.id)}),this._load_nodes(d,a.proxy(function(a){this.open_node(c,!1,0),this.select_node(e),this.trigger("refresh_node",{node:b,nodes:a})},this),!1,!0)},set_id:function(b,c){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var d,e,f=this._model.data,g=b.id;for(c=c.toString(),f[b.parent].children[a.inArray(b.id,f[b.parent].children)]=c,d=0,e=b.parents.length;e>d;d++)f[b.parents[d]].children_d[a.inArray(b.id,f[b.parents[d]].children_d)]=c;for(d=0,e=b.children.length;e>d;d++)f[b.children[d]].parent=c;for(d=0,e=b.children_d.length;e>d;d++)f[b.children_d[d]].parents[a.inArray(b.id,f[b.children_d[d]].parents)]=c;return d=a.inArray(b.id,this._data.core.selected),-1!==d&&(this._data.core.selected[d]=c),d=this.get_node(b.id,!0),d&&(d.attr("id",c),this.element.attr("aria-activedescendant")===b.id&&this.element.attr("aria-activedescendant",c)),delete f[b.id],b.id=c,b.li_attr.id=c,f[c]=b,this.trigger("set_id",{node:b,"new":b.id,old:g}),!0},get_text:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.text:!1},set_text:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.set_text(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.text=c,this.get_node(b,!0).length&&this.redraw_node(b.id),this.trigger("set_text",{obj:b,text:c}),!0):!1},get_json:function(b,c,d){if(b=this.get_node(b||a.jstree.root),!b)return!1;c&&c.flat&&!d&&(d=[]);var e={id:b.id,text:b.text,icon:this.get_icon(b),li_attr:a.extend(!0,{},b.li_attr),a_attr:a.extend(!0,{},b.a_attr),state:{},data:c&&c.no_data?!1:a.extend(!0,a.isArray(b.data)?[]:{},b.data)},f,g;if(c&&c.flat?e.parent=b.parent:e.children=[],c&&c.no_state)delete e.state;else for(f in b.state)b.state.hasOwnProperty(f)&&(e.state[f]=b.state[f]);if(c&&c.no_li_attr&&delete e.li_attr,c&&c.no_a_attr&&delete e.a_attr,c&&c.no_id&&(delete e.id,e.li_attr&&e.li_attr.id&&delete e.li_attr.id,e.a_attr&&e.a_attr.id&&delete e.a_attr.id),c&&c.flat&&b.id!==a.jstree.root&&d.push(e),!c||!c.no_children)for(f=0,g=b.children.length;g>f;f++)c&&c.flat?this.get_json(b.children[f],c,d):e.children.push(this.get_json(b.children[f],c));return c&&c.flat?d:b.id===a.jstree.root?e.children:e},create_node:function(c,d,e,f,g){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return!1;if(e=e===b?"last":e,!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(c))return this.load_node(c,function(){this.create_node(c,d,e,f,!0)});d||(d={text:this.get_string("New node")}),d="string"==typeof d?{text:d}:a.extend(!0,{},d),d.text===b&&(d.text=this.get_string("New node"));var h,i,j,k;switch(c.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":h=this.get_node(c.parent),e=a.inArray(c.id,h.children),c=h;break;case"after":h=this.get_node(c.parent),e=a.inArray(c.id,h.children)+1,c=h;break;case"inside":case"first":e=0;break;case"last":e=c.children.length;break;default:e||(e=0)}if(e>c.children.length&&(e=c.children.length),d.id||(d.id=!0),!this.check("create_node",d,c,e))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(d.id===!0&&delete d.id,d=this._parse_model_from_json(d,c.id,c.parents.concat()),!d)return!1;for(h=this.get_node(d),i=[],i.push(d),i=i.concat(h.children_d),this.trigger("model",{nodes:i,parent:c.id}),c.children_d=c.children_d.concat(i),j=0,k=c.parents.length;k>j;j++)this._model.data[c.parents[j]].children_d=this._model.data[c.parents[j]].children_d.concat(i);for(d=h,h=[],j=0,k=c.children.length;k>j;j++)h[j>=e?j+1:j]=c.children[j];return h[e]=d.id,c.children=h,this.redraw_node(c,!0),this.trigger("create_node",{node:this.get_node(d),parent:c.id,position:e}),f&&f.call(this,this.get_node(d)),d.id},rename_node:function(b,c){var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.rename_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=b.text,this.check("rename_node",b,this.get_parent(b),c)?(this.set_text(b,c),this.trigger("rename_node",{node:b,text:c,old:f}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.delete_node(b[c]);return!0}if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;if(e=this.get_node(b.parent),f=a.inArray(b.id,e.children),l=!1,!this.check("delete_node",b,e,f))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==f&&(e.children=a.vakata.array_remove(e.children,f)),g=b.children_d.concat([]),g.push(b.id),h=0,i=b.parents.length;i>h;h++)this._model.data[b.parents[h]].children_d=a.vakata.array_filter(this._model.data[b.parents[h]].children_d,function(b){return-1===a.inArray(b,g)});for(j=0,k=g.length;k>j;j++)if(this._model.data[g[j]].state.selected){l=!0;break}for(l&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(b){return-1===a.inArray(b,g)})),this.trigger("delete_node",{node:b,parent:e.id}),l&&this.trigger("changed",{action:"delete_node",node:b,selected:this._data.core.selected,parent:e.id}),j=0,k=g.length;k>j;j++)delete this._model.data[g[j]];return-1!==a.inArray(this._data.core.focused,g)&&(this._data.core.focused=null,m=this.element[0].scrollTop,n=this.element[0].scrollLeft,e.id===a.jstree.root?this._model.data[a.jstree.root].children[0]&&this.get_node(this._model.data[a.jstree.root].children[0],!0).children(".jstree-anchor").focus():this.get_node(e,!0).children(".jstree-anchor").focus(),this.element[0].scrollTop=m,this.element[0].scrollLeft=n),this.redraw_node(e,!0),!0},check:function(b,c,d,e,f){c=c&&c.id?c:this.get_node(c),d=d&&d.id?d:this.get_node(d);var g=b.match(/^move_node|copy_node|create_node$/i)?d:c,h=this.settings.core.check_callback;if("move_node"===b||"copy_node"===b){if(!(f&&f.is_multi||"move_node"!==b||a.inArray(c.id,d.children)!==e))return this._data.core.last_error={error:"check",plugin:"core",id:"core_08",reason:"Moving node to its current position",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1;if(!(f&&f.is_multi||c.id!==d.id&&("move_node"!==b||a.inArray(c.id,d.children)!==e)&&-1===a.inArray(d.id,c.children_d)))return this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1}return g&&g.data&&(g=g.data),g&&g.functions&&(g.functions[b]===!1||g.functions[b]===!0)?(g.functions[b]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})}),g.functions[b]):h===!1||a.isFunction(h)&&h.call(this,b,c,d,e,f)===!1||h&&h[b]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1):!0},last_error:function(){return this._data.core.last_error},move_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.move_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(r=this.move_node(c[j],d,e,f,g,!1,i))&&(d=r,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;if(l=(c.parent||a.jstree.root).toString(),n=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,o=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),p=!o||!o._id||this._id!==o._id,m=o&&o._id&&l&&o._model.data[l]&&o._model.data[l].children?a.inArray(c.id,o._model.data[l].children):-1,o&&o._id&&(c=o._model.data[c.id]),p)return(r=this.copy_node(c,d,e,f,g,!1,i))?(o&&o.delete_node(c),r):!1;switch(d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,n.children);break;case"after":e=a.inArray(d.id,n.children)+1;break;case"inside":case"first":e=0;break;case"last":e=n.children.length;break;default:e||(e=0)}if(e>n.children.length&&(e=n.children.length),!this.check("move_node",c,n,e,{core:!0,origin:i,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(c.parent===n.id){for(q=n.children.concat(),r=a.inArray(c.id,q),-1!==r&&(q=a.vakata.array_remove(q,r),e>r&&e--),r=[],s=0,t=q.length;t>s;s++)r[s>=e?s+1:s]=q[s];r[e]=c.id,n.children=r,this._node_changed(n.id),this.redraw(n.id===a.jstree.root)}else{for(r=c.children_d.concat(),r.push(c.id),s=0,t=c.parents.length;t>s;s++){for(q=[],w=o._model.data[c.parents[s]].children_d,u=0,v=w.length;v>u;u++)-1===a.inArray(w[u],r)&&q.push(w[u]);o._model.data[c.parents[s]].children_d=q}for(o._model.data[l].children=a.vakata.array_remove_item(o._model.data[l].children,c.id),s=0,t=n.parents.length;t>s;s++)this._model.data[n.parents[s]].children_d=this._model.data[n.parents[s]].children_d.concat(r);for(q=[],s=0,t=n.children.length;t>s;s++)q[s>=e?s+1:s]=n.children[s];for(q[e]=c.id,n.children=q,n.children_d.push(c.id),n.children_d=n.children_d.concat(c.children_d),c.parent=n.id,r=n.parents.concat(),r.unshift(n.id),w=c.parents.length,c.parents=r,r=r.concat(),s=0,t=c.children_d.length;t>s;s++)this._model.data[c.children_d[s]].parents=this._model.data[c.children_d[s]].parents.slice(0,-1*w),Array.prototype.push.apply(this._model.data[c.children_d[s]].parents,r);(l===a.jstree.root||n.id===a.jstree.root)&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||(this._node_changed(l),this._node_changed(n.id)),h||this.redraw()}return f&&f.call(this,c,n,e),this.trigger("move_node",{node:c,parent:n.id,position:e,old_parent:l,old_position:m,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id,old_instance:o,new_instance:this}),c.id},copy_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.copy_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(m=this.copy_node(c[j],d,e,f,g,!0,i))&&(d=m,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;switch(q=(c.parent||a.jstree.root).toString(),r=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,s=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),t=!s||!s._id||this._id!==s._id,s&&s._id&&(c=s._model.data[c.id]),d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,r.children);break;case"after":e=a.inArray(d.id,r.children)+1;break;case"inside":case"first":e=0;break;case"last":e=r.children.length;break;default:e||(e=0)}if(e>r.children.length&&(e=r.children.length),!this.check("copy_node",c,r,e,{core:!0,origin:i,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(p=s?s.get_json(c,{no_id:!0,no_data:!0,no_state:!0}):c,!p)return!1;if(p.id===!0&&delete p.id,p=this._parse_model_from_json(p,r.id,r.parents.concat()), +!p)return!1;for(m=this.get_node(p),c&&c.state&&c.state.loaded===!1&&(m.state.loaded=!1),l=[],l.push(p),l=l.concat(m.children_d),this.trigger("model",{nodes:l,parent:r.id}),n=0,o=r.parents.length;o>n;n++)this._model.data[r.parents[n]].children_d=this._model.data[r.parents[n]].children_d.concat(l);for(l=[],n=0,o=r.children.length;o>n;n++)l[n>=e?n+1:n]=r.children[n];return l[e]=m.id,r.children=l,r.children_d.push(m.id),r.children_d=r.children_d.concat(m.children_d),r.id===a.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(r.id),h||this.redraw(r.id===a.jstree.root),f&&f.call(this,m,r,e),this.trigger("copy_node",{node:m,original:c,parent:r.id,position:e,old_parent:q,old_position:s&&s._id&&q&&s._model.data[q]&&s._model.data[q].children?a.inArray(c.id,s._model.data[q].children):-1,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id,old_instance:s,new_instance:this}),m.id},cut:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="move_node",void this.trigger("cut",{node:b})):!1},copy:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="copy_node",void this.trigger("copy",{node:b})):!1},get_buffer:function(){return{mode:e,node:d,inst:f}},can_paste:function(){return e!==!1&&d!==!1},paste:function(a,b){return a=this.get_node(a),a&&e&&e.match(/^(copy_node|move_node)$/)&&d?(this[e](d,a,b,!1,!1,!1,f)&&this.trigger("paste",{parent:a.id,node:d,mode:e}),d=!1,e=!1,void(f=!1)):!1},clear_buffer:function(){d=!1,e=!1,f=!1,this.trigger("clear_buffer")},edit:function(b,c,d){var e,f,g,h,j,k,l,m,n,o=!1;return(b=this.get_node(b))?this.check("edit",b,this.get_parent(b))?(n=b,c="string"==typeof c?c:b.text,this.set_text(b,""),b=this._open_to(b),n.text=c,e=this._data.core.rtl,f=this.element.width(),this._data.core.focused=n.id,g=b.children(".jstree-anchor").focus(),h=a(""),j=c,k=a("
      ",{css:{position:"absolute",top:"-200px",left:e?"0px":"-1000px",visibility:"hidden"}}).appendTo(i.body),l=a("",{value:j,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:a.proxy(function(c){c.stopImmediatePropagation(),c.preventDefault();var e=h.children(".jstree-rename-input"),f=e.val(),i=this.settings.core.force_text,m;""===f&&(f=j),k.remove(),h.replaceWith(g),h.remove(),j=i?j:a("
      ").append(a.parseHTML(j)).html(),b=this.get_node(b),this.set_text(b,j),m=!!this.rename_node(b,i?a("
      ").text(f).text():a("
      ").append(a.parseHTML(f)).html()),m||this.set_text(b,j),this._data.core.focused=n.id,setTimeout(a.proxy(function(){var a=this.get_node(n.id,!0);a.length&&(this._data.core.focused=n.id,a.children(".jstree-anchor").focus())},this),0),d&&d.call(this,n,m,o),l=null},this),keydown:function(a){var b=a.which;27===b&&(o=!0,this.value=j),(27===b||13===b||37===b||38===b||39===b||40===b||32===b)&&a.stopImmediatePropagation(),(27===b||13===b)&&(a.preventDefault(),this.blur())},click:function(a){a.stopImmediatePropagation()},mousedown:function(a){a.stopImmediatePropagation()},keyup:function(a){l.width(Math.min(k.text("pW"+this.value).width(),f))},keypress:function(a){return 13===a.which?!1:void 0}}),m={fontFamily:g.css("fontFamily")||"",fontSize:g.css("fontSize")||"",fontWeight:g.css("fontWeight")||"",fontStyle:g.css("fontStyle")||"",fontStretch:g.css("fontStretch")||"",fontVariant:g.css("fontVariant")||"",letterSpacing:g.css("letterSpacing")||"",wordSpacing:g.css("wordSpacing")||""},h.attr("class",g.attr("class")).append(g.contents().clone()).append(l),g.replaceWith(h),k.css(m),l.css(m).width(Math.min(k.text("pW"+l[0].value).width(),f))[0].select(),void a(i).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(b){l&&b.target!==l&&a(l).blur()})):(this.settings.core.error.call(this,this._data.core.last_error),!1):!1},set_theme:function(b,c){if(!b)return!1;if(c===!0){var d=this.settings.core.themes.dir;d||(d=a.jstree.path+"/themes"),c=d+"/"+b+"/style.css"}c&&-1===a.inArray(c,g)&&(a("head").append(''),g.push(c)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=b,this.element.addClass("jstree-"+b),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+b+"-responsive"),this.trigger("set_theme",{theme:b})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(a){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=a,a&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped"),this.trigger("show_stripes")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped"),this.trigger("hide_stripes")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots"),this.trigger("show_dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots"),this.trigger("hide_dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons"),this.trigger("show_icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons"),this.trigger("hide_icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},show_ellipsis:function(){this._data.core.themes.ellipsis=!0,this.get_container_ul().addClass("jstree-ellipsis"),this.trigger("show_ellipsis")},hide_ellipsis:function(){this._data.core.themes.ellipsis=!1,this.get_container_ul().removeClass("jstree-ellipsis"),this.trigger("hide_ellipsis")},toggle_ellipsis:function(){this._data.core.themes.ellipsis?this.hide_ellipsis():this.show_ellipsis()},set_icon:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.set_icon(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(h=c.icon,c.icon=d===!0||null===d||d===b||""===d?!0:d,g=this.get_node(c,!0).children(".jstree-anchor").children(".jstree-themeicon"),d===!1?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),this.hide_icon(c)):d===!0||null===d||d===b||""===d?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),h===!1&&this.show_icon(c)):-1===d.indexOf("/")&&-1===d.indexOf(".")?(g.removeClass(h).css("background",""),g.addClass(d+" jstree-themeicon-custom").attr("rel",d),h===!1&&this.show_icon(c)):(g.removeClass(h).css("background",""),g.addClass("jstree-themeicon-custom").css("background","url('"+d+"') center center no-repeat").attr("rel",d),h===!1&&this.show_icon(c)),!0):!1},get_icon:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.icon:!1},hide_icon:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.hide_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(b.icon=!1,this.get_node(b,!0).children(".jstree-anchor").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.show_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(e=this.get_node(b,!0),b.icon=e.length?e.children(".jstree-anchor").children(".jstree-themeicon").attr("rel"):!0,b.icon||(b.icon=!0),e.children(".jstree-anchor").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},a.vakata={},a.vakata.attributes=function(b,c){b=a(b)[0];var d=c?{}:[];return b&&b.attributes&&a.each(b.attributes,function(b,e){-1===a.inArray(e.name.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==e.value&&""!==a.trim(e.value)&&(c?d[e.name]=e.value:d.push(e.name))}),d},a.vakata.array_unique=function(a){var c=[],d,e,f,g={};for(d=0,f=a.length;f>d;d++)g[a[d]]===b&&(c.push(a[d]),g[a[d]]=!0);return c},a.vakata.array_remove=function(a,b){return a.splice(b,1),a},a.vakata.array_remove_item=function(b,c){var d=a.inArray(c,b);return-1!==d?a.vakata.array_remove(b,d):b},a.vakata.array_filter=function(a,b,c,d,e){if(a.filter)return a.filter(b,c);d=[];for(e in a)~~e+""==e+""&&e>=0&&b.call(c,a[e],+e,a)&&d.push(a[e]);return d},a.jstree.plugins.changed=function(a,b){var c=[];this.trigger=function(a,d){var e,f;if(d||(d={}),"changed"===a.replace(".jstree","")){d.changed={selected:[],deselected:[]};var g={};for(e=0,f=c.length;f>e;e++)g[c[e]]=1;for(e=0,f=d.selected.length;f>e;e++)g[d.selected[e]]?g[d.selected[e]]=2:d.changed.selected.push(d.selected[e]);for(e=0,f=c.length;f>e;e++)1===g[c[e]]&&d.changed.deselected.push(c[e]);c=d.selected.slice()}b.trigger.call(this,a,d)},this.refresh=function(a,d){return c=[],b.refresh.apply(this,arguments)}};var l=i.createElement("I");l.className="jstree-icon jstree-checkbox",l.setAttribute("role","presentation"),a.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0,cascade:"",tie_selection:!0,cascade_to_disabled:!0,cascade_to_hidden:!0},a.jstree.plugins.checkbox=function(c,d){this.bind=function(){d.bind.call(this),this._data.checkbox.uto=!1,this._data.checkbox.selected=[],this.settings.checkbox.three_state&&(this.settings.checkbox.cascade="up+down+undetermined"),this.element.on("init.jstree",a.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked"),this.settings.checkbox.tie_selection&&this.element.addClass("jstree-checkbox-selection")},this)).on("loading.jstree",a.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),-1!==this.settings.checkbox.cascade.indexOf("undetermined")&&this.element.on("changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",a.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)},this)),this.settings.checkbox.tie_selection||this.element.on("model.jstree",a.proxy(function(a,b){var c=this._model.data,d=c[b.parent],e=b.nodes,f,g;for(f=0,g=e.length;g>f;f++)c[e[f]].state.checked=c[e[f]].state.checked||c[e[f]].original&&c[e[f]].original.state&&c[e[f]].original.state.checked,c[e[f]].state.checked&&this._data.checkbox.selected.push(e[f])},this)),(-1!==this.settings.checkbox.cascade.indexOf("up")||-1!==this.settings.checkbox.cascade.indexOf("down"))&&this.element.on("model.jstree",a.proxy(function(b,c){var d=this._model.data,e=d[c.parent],f=c.nodes,g=[],h,i,j,k,l,m,n=this.settings.checkbox.cascade,o=this.settings.checkbox.tie_selection;if(-1!==n.indexOf("down"))if(e.state[o?"selected":"checked"]){for(i=0,j=f.length;j>i;i++)d[f[i]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(f)}else for(i=0,j=f.length;j>i;i++)if(d[f[i]].state[o?"selected":"checked"]){for(k=0,l=d[f[i]].children_d.length;l>k;k++)d[d[f[i]].children_d[k]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(d[f[i]].children_d)}if(-1!==n.indexOf("up")){for(i=0,j=e.children_d.length;j>i;i++)d[e.children_d[i]].children.length||g.push(d[e.children_d[i]].parent);for(g=a.vakata.array_unique(g),k=0,l=g.length;l>k;k++){e=d[g[k]];while(e&&e.id!==a.jstree.root){for(h=0,i=0,j=e.children.length;j>i;i++)h+=d[e.children[i]].state[o?"selected":"checked"];if(h!==j)break;e.state[o?"selected":"checked"]=!0,this._data[o?"core":"checkbox"].selected.push(e.id),m=this.get_node(e,!0),m&&m.length&&m.attr("aria-selected",!0).children(".jstree-anchor").addClass(o?"jstree-clicked":"jstree-checked"),e=this.get_node(e.parent)}}}this._data[o?"core":"checkbox"].selected=a.vakata.array_unique(this._data[o?"core":"checkbox"].selected)},this)).on(this.settings.checkbox.tie_selection?"select_node.jstree":"check_node.jstree",a.proxy(function(b,c){var d=this,e=c.node,f=this._model.data,g=this.get_node(e.parent),h,i,j,k,l=this.settings.checkbox.cascade,m=this.settings.checkbox.tie_selection,n={},o=this._data[m?"core":"checkbox"].selected;for(h=0,i=o.length;i>h;h++)n[o[h]]=!0;if(-1!==l.indexOf("down")){var p=this._cascade_new_checked_state(e.id,!0),q=e.children_d.concat(e.id);for(h=0,i=q.length;i>h;h++)p.indexOf(q[h])>-1?n[q[h]]=!0:delete n[q[h]]}if(-1!==l.indexOf("up"))while(g&&g.id!==a.jstree.root){for(j=0,h=0,i=g.children.length;i>h;h++)j+=f[g.children[h]].state[m?"selected":"checked"];if(j!==i)break;g.state[m?"selected":"checked"]=!0,n[g.id]=!0,k=this.get_node(g,!0),k&&k.length&&k.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),g=this.get_node(g.parent)}o=[];for(h in n)n.hasOwnProperty(h)&&o.push(h);this._data[m?"core":"checkbox"].selected=o},this)).on(this.settings.checkbox.tie_selection?"deselect_all.jstree":"uncheck_all.jstree",a.proxy(function(b,c){var d=this.get_node(a.jstree.root),e=this._model.data,f,g,h;for(f=0,g=d.children_d.length;g>f;f++)h=e[d.children_d[f]],h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1)},this)).on(this.settings.checkbox.tie_selection?"deselect_node.jstree":"uncheck_node.jstree",a.proxy(function(b,c){var d=this,e=c.node,f=this.get_node(e,!0),g,h,i,j=this.settings.checkbox.cascade,k=this.settings.checkbox.tie_selection,l=this._data[k?"core":"checkbox"].selected,m={},n=[],o=e.children_d.concat(e.id);if(-1!==j.indexOf("down")){var p=this._cascade_new_checked_state(e.id,!1);l=a.vakata.array_filter(l,function(a){return-1===o.indexOf(a)||p.indexOf(a)>-1})}if(-1!==j.indexOf("up")&&-1===l.indexOf(e.id)){for(g=0,h=e.parents.length;h>g;g++)i=this._model.data[e.parents[g]],i.state[k?"selected":"checked"]=!1,i&&i.original&&i.original.state&&i.original.state.undetermined&&(i.original.state.undetermined=!1),i=this.get_node(e.parents[g],!0),i&&i.length&&i.attr("aria-selected",!1).children(".jstree-anchor").removeClass(k?"jstree-clicked":"jstree-checked");l=a.vakata.array_filter(l,function(a){return-1===e.parents.indexOf(a)})}this._data[k?"core":"checkbox"].selected=l},this)),-1!==this.settings.checkbox.cascade.indexOf("up")&&this.element.on("delete_node.jstree",a.proxy(function(b,c){var d=this.get_node(c.parent),e=this._model.data,f,g,h,i,j=this.settings.checkbox.tie_selection;while(d&&d.id!==a.jstree.root&&!d.state[j?"selected":"checked"]){for(h=0,f=0,g=d.children.length;g>f;f++)h+=e[d.children[f]].state[j?"selected":"checked"];if(!(g>0&&h===g))break;d.state[j?"selected":"checked"]=!0,this._data[j?"core":"checkbox"].selected.push(d.id),i=this.get_node(d,!0),i&&i.length&&i.attr("aria-selected",!0).children(".jstree-anchor").addClass(j?"jstree-clicked":"jstree-checked"),d=this.get_node(d.parent)}},this)).on("move_node.jstree",a.proxy(function(b,c){var d=c.is_multi,e=c.old_parent,f=this.get_node(c.parent),g=this._model.data,h,i,j,k,l,m=this.settings.checkbox.tie_selection;if(!d){h=this.get_node(e);while(h&&h.id!==a.jstree.root&&!h.state[m?"selected":"checked"]){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(!(k>0&&i===k))break;h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),h=this.get_node(h.parent)}}h=f;while(h&&h.id!==a.jstree.root){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(i===k)h.state[m?"selected":"checked"]||(h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"));else{if(!h.state[m?"selected":"checked"])break;h.state[m?"selected":"checked"]=!1,this._data[m?"core":"checkbox"].selected=a.vakata.array_remove_item(this._data[m?"core":"checkbox"].selected,h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!1).children(".jstree-anchor").removeClass(m?"jstree-clicked":"jstree-checked")}h=this.get_node(h.parent)}},this))},this.get_undetermined=function(c){if(-1===this.settings.checkbox.cascade.indexOf("undetermined"))return[];var d,e,f,g,h={},i=this._model.data,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l=[],m=this,n=[];for(d=0,e=k.length;e>d;d++)if(i[k[d]]&&i[k[d]].parents)for(f=0,g=i[k[d]].parents.length;g>f;f++){if(h[i[k[d]].parents[f]]!==b)break;i[k[d]].parents[f]!==a.jstree.root&&(h[i[k[d]].parents[f]]=!0,l.push(i[k[d]].parents[f]))}for(this.element.find(".jstree-closed").not(":has(.jstree-children)").each(function(){var c=m.get_node(this),j;if(c)if(c.state.loaded){for(d=0,e=c.children_d.length;e>d;d++)if(j=i[c.children_d[d]],!j.state.loaded&&j.original&&j.original.state&&j.original.state.undetermined&&j.original.state.undetermined===!0)for(h[j.id]===b&&j.id!==a.jstree.root&&(h[j.id]=!0,l.push(j.id)),f=0,g=j.parents.length;g>f;f++)h[j.parents[f]]===b&&j.parents[f]!==a.jstree.root&&(h[j.parents[f]]=!0,l.push(j.parents[f]))}else if(c.original&&c.original.state&&c.original.state.undetermined&&c.original.state.undetermined===!0)for(h[c.id]===b&&c.id!==a.jstree.root&&(h[c.id]=!0,l.push(c.id)),f=0,g=c.parents.length;g>f;f++)h[c.parents[f]]===b&&c.parents[f]!==a.jstree.root&&(h[c.parents[f]]=!0,l.push(c.parents[f]))}),d=0,e=l.length;e>d;d++)i[l[d]].state[j?"selected":"checked"]||n.push(c?i[l[d]]:l[d]);return n},this._undetermined=function(){if(null!==this.element){var a=this.get_undetermined(!1),b,c,d;for(this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),b=0,c=a.length;c>b;b++)d=this.get_node(a[b],!0),d&&d.length&&d.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-undetermined")}},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments)){var g,h,i=null,j=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(!this.settings.checkbox.tie_selection&&this._model.data[b.id].state.checked&&(i.className+=" jstree-checked"),j=l.cloneNode(!1),this._model.data[b.id].state.checkbox_disabled&&(j.className+=" jstree-checkbox-disabled"),i.insertBefore(j,i.childNodes[0]))}return e||-1===this.settings.checkbox.cascade.indexOf("undetermined")||(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)),b},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.get_container_ul().removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.get_container_ul().addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()},this.is_undetermined=function(b){b=this.get_node(b);var c=this.settings.checkbox.cascade,d,e,f=this.settings.checkbox.tie_selection,g=this._data[f?"core":"checkbox"].selected,h=this._model.data;if(!b||b.state[f?"selected":"checked"]===!0||-1===c.indexOf("undetermined")||-1===c.indexOf("down")&&-1===c.indexOf("up"))return!1;if(!b.state.loaded&&b.original.state.undetermined===!0)return!0;for(d=0,e=b.children_d.length;e>d;d++)if(-1!==a.inArray(b.children_d[d],g)||!h[b.children_d[d]].state.loaded&&h[b.children_d[d]].original.state.undetermined)return!0;return!1},this.disable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled||(b.state.checkbox_disabled=!0,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-checkbox-disabled"),this.trigger("disable_checkbox",{node:b})))):!1},this.enable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled&&(b.state.checkbox_disabled=!1,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").removeClass("jstree-checkbox-disabled"),this.trigger("enable_checkbox",{node:b})))):!1},this.activate_node=function(b,c){return a(c.target).hasClass("jstree-checkbox-disabled")?!1:(this.settings.checkbox.tie_selection&&(this.settings.checkbox.whole_node||a(c.target).hasClass("jstree-checkbox"))&&(c.ctrlKey=!0),this.settings.checkbox.tie_selection||!this.settings.checkbox.whole_node&&!a(c.target).hasClass("jstree-checkbox")?d.activate_node.call(this,b,c):this.is_disabled(b)?!1:(this.is_checked(b)?this.uncheck_node(b,c):this.check_node(b,c),void this.trigger("activate_node",{node:this.get_node(b)})))},this._cascade_new_checked_state=function(a,b){var c=this,d=this.settings.checkbox.tie_selection,e=this._model.data[a],f=[],g=[],h,i,j;if(!this.settings.checkbox.cascade_to_disabled&&e.state.disabled||!this.settings.checkbox.cascade_to_hidden&&e.state.hidden)j=this.get_checked_descendants(a),e.state[d?"selected":"checked"]&&j.push(e.id),f=f.concat(j);else{if(e.children)for(h=0,i=e.children.length;i>h;h++){var k=e.children[h];j=c._cascade_new_checked_state(k,b),f=f.concat(j),j.indexOf(k)>-1&&g.push(k)}var l=c.get_node(e,!0),m=g.length>0&&g.lengthe;e++)this.check_node(b[e],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(d=this.get_node(b,!0),void(b.state.checked||(b.state.checked=!0,this._data.checkbox.selected.push(b.id),d&&d.length&&d.children(".jstree-anchor").addClass("jstree-checked"),this.trigger("check_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.uncheck_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.deselect_node(b,!1,c);var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.uncheck_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.checked&&(b.state.checked=!1,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,b.id),f.length&&f.children(".jstree-anchor").removeClass("jstree-checked"),this.trigger("uncheck_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.check_all=function(){if(this.settings.checkbox.tie_selection)return this.select_all();var b=this._data.checkbox.selected.concat([]),c,d;for(this._data.checkbox.selected=this._model.data[a.jstree.root].children_d.concat(),c=0,d=this._data.checkbox.selected.length;d>c;c++)this._model.data[this._data.checkbox.selected[c]]&&(this._model.data[this._data.checkbox.selected[c]].state.checked=!0);this.redraw(!0),this.trigger("check_all",{selected:this._data.checkbox.selected})},this.uncheck_all=function(){if(this.settings.checkbox.tie_selection)return this.deselect_all();var a=this._data.checkbox.selected.concat([]),b,c;for(b=0,c=this._data.checkbox.selected.length;c>b;b++)this._model.data[this._data.checkbox.selected[b]]&&(this._model.data[this._data.checkbox.selected[b]].state.checked=!1);this._data.checkbox.selected=[],this.element.find(".jstree-checked").removeClass("jstree-checked"),this.trigger("uncheck_all",{selected:this._data.checkbox.selected,node:a})},this.is_checked=function(b){return this.settings.checkbox.tie_selection?this.is_selected(b):(b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.checked:!1)},this.get_checked=function(b){return this.settings.checkbox.tie_selection?this.get_selected(b):b?a.map(this._data.checkbox.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.checkbox.selected.slice()},this.get_top_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_top_selected(b);var c=this.get_checked(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},this.get_bottom_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_bottom_selected(b);var c=this.get_checked(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},this.load_node=function(b,c){var e,f,g,h,i,j;if(!a.isArray(b)&&!this.settings.checkbox.tie_selection&&(j=this.get_node(b),j&&j.state.loaded))for(e=0,f=j.children_d.length;f>e;e++)this._model.data[j.children_d[e]].state.checked&&(i=!0,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,j.children_d[e]));return d.load_node.apply(this,arguments)},this.get_state=function(){var a=d.get_state.apply(this,arguments);return this.settings.checkbox.tie_selection?a:(a.checkbox=this._data.checkbox.selected.slice(),a)},this.set_state=function(b,c){var e=d.set_state.apply(this,arguments);if(e&&b.checkbox){if(!this.settings.checkbox.tie_selection){this.uncheck_all();var f=this;a.each(b.checkbox,function(a,b){f.check_node(b)})}return delete b.checkbox,this.set_state(b,c),!1}return e},this.refresh=function(a,b){return this.settings.checkbox.tie_selection&&(this._data.checkbox.selected=[]),d.refresh.apply(this,arguments)}},a.jstree.defaults.conditionalselect=function(){return!0},a.jstree.plugins.conditionalselect=function(a,b){this.activate_node=function(a,c){return this.settings.conditionalselect.call(this,this.get_node(a),c)?b.activate_node.call(this,a,c):void 0}},a.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(b,c){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.create_node(d,{},"last",function(a){try{c.edit(a)}catch(b){setTimeout(function(){c.edit(a)},0)}})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.edit(d)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.delete_node(c.get_selected()):c.delete_node(d)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.cut(c.get_top_selected()):c.cut(d)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.copy(c.get_top_selected()):c.copy(d)}},paste:{separator_before:!1,icon:!1,_disabled:function(b){return!a.jstree.reference(b.reference).can_paste()},separator_after:!1,label:"Paste",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.paste(d)}}}}}}},a.jstree.plugins.contextmenu=function(c,d){this.bind=function(){d.bind.call(this);var b=0,c=null,e,f;this.element.on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-contextmenu")},this)).on("contextmenu.jstree",".jstree-anchor",a.proxy(function(a,d){"input"!==a.target.tagName.toLowerCase()&&(a.preventDefault(),b=a.ctrlKey?+new Date:0,(d||c)&&(b=+new Date+1e4),c&&clearTimeout(c),this.is_loading(a.currentTarget)||this.show_contextmenu(a.currentTarget,a.pageX,a.pageY,a))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(c){this._data.contextmenu.visible&&(!b||+new Date-b>250)&&a.vakata.context.hide(),b=0},this)).on("touchstart.jstree",".jstree-anchor",function(b){b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(e=b.originalEvent.changedTouches[0].clientX,f=b.originalEvent.changedTouches[0].clientY,c=setTimeout(function(){a(b.currentTarget).trigger("contextmenu",!0)},750))}).on("touchmove.vakata.jstree",function(b){c&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(Math.abs(e-b.originalEvent.changedTouches[0].clientX)>10||Math.abs(f-b.originalEvent.changedTouches[0].clientY)>10)&&(clearTimeout(c),a.vakata.context.hide())}).on("touchend.vakata.jstree",function(a){c&&clearTimeout(c)}),a(i).on("context_hide.vakata.jstree",a.proxy(function(b,c){this._data.contextmenu.visible=!1,a(c.reference).removeClass("jstree-context")},this))},this.teardown=function(){this._data.contextmenu.visible&&a.vakata.context.hide(),d.teardown.call(this)},this.show_contextmenu=function(c,d,e,f){if(c=this.get_node(c),!c||c.id===a.jstree.root)return!1;var g=this.settings.contextmenu,h=this.get_node(c,!0),i=h.children(".jstree-anchor"),j=!1,k=!1;(g.show_at_node||d===b||e===b)&&(j=i.offset(),d=j.left,e=j.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(c)&&this.activate_node(c,f),k=g.items,a.isFunction(k)&&(k=k.call(this,c,a.proxy(function(a){this._show_contextmenu(c,d,e,a)},this))),a.isPlainObject(k)&&this._show_contextmenu(c,d,e,k)},this._show_contextmenu=function(b,c,d,e){var f=this.get_node(b,!0),g=f.children(".jstree-anchor");a(i).one("context_show.vakata.jstree",a.proxy(function(b,c){var d="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";a(c.element).addClass(d),g.addClass("jstree-context")},this)),this._data.contextmenu.visible=!0,a.vakata.context.show(g,{x:c,y:d},e),this.trigger("show_contextmenu",{node:b,x:c,y:d})}},function(a){var b=!1,c={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};a.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(b){a(i).triggerHandler("context_"+b+".vakata",{reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}})},_execute:function(b){return b=c.items[b],b&&(!b._disabled||a.isFunction(b._disabled)&&!b._disabled({ +item:b,reference:c.reference,element:c.element}))&&b.action?b.action.call(null,{item:b,reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}}):!1},_parse:function(b,d){if(!b)return!1;d||(c.html="",c.items=[]);var e="",f=!1,g;return d&&(e+=""),d||(c.html=e,a.vakata.context._trigger("parse")),e.length>10?e:!1},_show_submenu:function(c){if(c=a(c),c.length&&c.children("ul").length){var d=c.children("ul"),e=c.offset().left,f=e+c.outerWidth(),g=c.offset().top,h=d.width(),i=d.height(),j=a(window).width()+a(window).scrollLeft(),k=a(window).height()+a(window).scrollTop();b?c[f-(h+10+c.outerWidth())<0?"addClass":"removeClass"]("vakata-context-left"):c[f+h>j&&e>j-f?"addClass":"removeClass"]("vakata-context-right"),g+i+10>k&&d.css("bottom","-1px"),c.hasClass("vakata-context-right")?h>e&&d.css("margin-right",e-h):h>j-f&&d.css("margin-left",j-f-h),d.show()}},show:function(d,e,f){var g,h,j,k,l,m,n,o,p=!0;switch(c.element&&c.element.length&&c.element.width(""),p){case!e&&!d:return!1;case!!e&&!!d:c.reference=d,c.position_x=e.x,c.position_y=e.y;break;case!e&&!!d:c.reference=d,g=d.offset(),c.position_x=g.left+d.outerHeight(),c.position_y=g.top;break;case!!e&&!d:c.position_x=e.x,c.position_y=e.y}d&&!f&&a(d).data("vakata_contextmenu")&&(f=a(d).data("vakata_contextmenu")),a.vakata.context._parse(f)&&c.element.html(c.html),c.items.length&&(c.element.appendTo(i.body),h=c.element,j=c.position_x,k=c.position_y,l=h.width(),m=h.height(),n=a(window).width()+a(window).scrollLeft(),o=a(window).height()+a(window).scrollTop(),b&&(j-=h.outerWidth()-a(d).outerWidth(),jn&&(j=n-(l+20)),k+m+20>o&&(k=o-(m+20)),c.element.css({left:j,top:k}).show().find("a").first().focus().parent().addClass("vakata-context-hover"),c.is_visible=!0,a.vakata.context._trigger("show"))},hide:function(){c.is_visible&&(c.element.hide().find("ul").hide().end().find(":focus").blur().end().detach(),c.is_visible=!1,a.vakata.context._trigger("hide"))}},a(function(){b="rtl"===a(i.body).css("direction");var d=!1;c.element=a("
        "),c.element.on("mouseenter","li",function(b){b.stopImmediatePropagation(),a.contains(this,b.relatedTarget)||(d&&clearTimeout(d),c.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),a(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),a.vakata.context._show_submenu(this))}).on("mouseleave","li",function(b){a.contains(this,b.relatedTarget)||a(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(b){a(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),a.vakata.context.settings.hide_onmouseleave&&(d=setTimeout(function(b){return function(){a.vakata.context.hide()}}(this),a.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(b){b.preventDefault(),a(this).blur().parent().hasClass("vakata-context-disabled")||a.vakata.context._execute(a(this).attr("rel"))===!1||a.vakata.context.hide()}).on("keydown","a",function(b){var d=null;switch(b.which){case 13:case 32:b.type="click",b.preventDefault(),a(b.currentTarget).trigger(b);break;case 37:c.is_visible&&(c.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 38:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 39:c.is_visible&&(c.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 40:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 27:a.vakata.context.hide(),b.preventDefault()}}).on("keydown",function(a){a.preventDefault();var b=c.element.find(".vakata-contextmenu-shortcut-"+a.which).parent();b.parent().not(".vakata-context-disabled")&&b.click()}),a(i).on("mousedown.vakata.jstree",function(b){c.is_visible&&c.element[0]!==b.target&&!a.contains(c.element[0],b.target)&&a.vakata.context.hide()}).on("context_show.vakata.jstree",function(a,d){c.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),b&&c.element.addClass("vakata-context-rtl").css("direction","rtl"),c.element.find("ul").hide().end()})})}(a),a.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1};var m,n;a.jstree.plugins.dnd=function(b,c){this.init=function(a,b){c.init.call(this,a,b),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in i.createElement("span")},this.bind=function(){c.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",a.proxy(function(b){if(this.settings.dnd.large_drag_target&&a(b.target).closest(".jstree-node")[0]!==b.currentTarget)return!0;if("touchstart"===b.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var c=this.get_node(b.target),d=this.is_selected(c)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,e=d>1?d+" "+this.get_string("nodes"):this.get_text(b.currentTarget);if(this.settings.core.force_text&&(e=a.vakata.html.escape(e)),c&&c.id&&c.id!==a.jstree.root&&(1===b.which||"touchstart"===b.type||"dragstart"===b.type)&&(this.settings.dnd.is_draggable===!0||a.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,d>1?this.get_top_selected(!0):[c],b))){if(m={jstree:!0,origin:this,obj:this.get_node(c,!0),nodes:d>1?this.get_top_selected():[c.id]},n=b.currentTarget,!this.settings.dnd.use_html5)return this.element.trigger("mousedown.jstree"),a.vakata.dnd.start(b,m,'
        '+e+'
        ');a.vakata.dnd._trigger("start",b,{helper:a(),element:n,data:m})}},this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(b){return b.preventDefault(),a.vakata.dnd._trigger("move",b,{helper:a(),element:n,data:m}),!1}).on("drop.jstree",a.proxy(function(b){return b.preventDefault(),a.vakata.dnd._trigger("stop",b,{helper:a(),element:n,data:m}),!1},this))},this.redraw_node=function(a,b,d,e){if(a=c.redraw_node.apply(this,arguments),a&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)a.setAttribute("draggable",!0);else{var f,g,h=null;for(f=0,g=a.childNodes.length;g>f;f++)if(a.childNodes[f]&&a.childNodes[f].className&&-1!==a.childNodes[f].className.indexOf("jstree-anchor")){h=a.childNodes[f];break}h&&h.setAttribute("draggable",!0)}return a}},a(function(){var c=!1,d=!1,e=!1,f=!1,g=a('
         
        ').hide();a(i).on("dragover.vakata.jstree",function(b){n&&a.vakata.dnd._trigger("move",b,{helper:a(),element:n,data:m})}).on("drop.vakata.jstree",function(b){n&&(a.vakata.dnd._trigger("stop",b,{helper:a(),element:n,data:m}),n=null,m=null)}).on("dnd_start.vakata.jstree",function(a,b){c=!1,e=!1,b&&b.data&&b.data.jstree&&g.appendTo(i.body)}).on("dnd_move.vakata.jstree",function(h,i){var j=i.event.target!==e.target;if(f&&(!i.event||"dragover"!==i.event.type||j)&&clearTimeout(f),i&&i.data&&i.data.jstree&&(!i.event.target.id||"jstree-marker"!==i.event.target.id)){e=i.event;var k=a.jstree.reference(i.event.target),l=!1,m=!1,n=!1,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F;if(k&&k._data&&k._data.dnd)if(g.attr("class","jstree-"+k.get_theme()+(k.settings.core.themes.responsive?" jstree-dnd-responsive":"")),D=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey)),i.helper.children().attr("class","jstree-"+k.get_theme()+" jstree-"+k.get_theme()+"-"+k.get_theme_variant()+" "+(k.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[D?"show":"hide"](),i.event.target!==k.element[0]&&i.event.target!==k.get_container_ul()[0]||0!==k.get_container_ul().children().length){if(l=k.settings.dnd.large_drop_target?a(i.event.target).closest(".jstree-node").children(".jstree-anchor"):a(i.event.target).closest(".jstree-anchor"),l&&l.length&&l.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(m=l.offset(),n=(i.event.pageY!==b?i.event.pageY:i.event.originalEvent.pageY)-m.top,r=l.outerHeight(),u=r/3>n?["b","i","a"]:n>r-r/3?["a","i","b"]:n>r/2?["i","a","b"]:["i","b","a"],a.each(u,function(b,e){switch(e){case"b":p=m.left-6,q=m.top,s=k.get_parent(l),t=l.parent().index(),F="jstree-below";break;case"i":B=k.settings.dnd.inside_pos,C=k.get_node(l.parent()),p=m.left-2,q=m.top+r/2+1,s=C.id,t="first"===B?0:"last"===B?C.children.length:Math.min(B,C.children.length),F="jstree-inside";break;case"a":p=m.left-6,q=m.top+r,s=k.get_parent(l),t=l.parent().index()+1,F="jstree-above"}for(v=!0,w=0,x=i.data.nodes.length;x>w;w++)if(y=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",z=t,"move_node"===y&&"a"===e&&i.data.origin&&i.data.origin===k&&s===k.get_parent(i.data.nodes[w])&&(A=k.get_node(s),z>a.inArray(i.data.nodes[w],A.children)&&(z-=1)),v=v&&(k&&k.settings&&k.settings.dnd&&k.settings.dnd.check_while_dragging===!1||k.check(y,i.data.origin&&i.data.origin!==k?i.data.origin.get_node(i.data.nodes[w]):i.data.nodes[w],s,z,{dnd:!0,ref:k.get_node(l.parent()),pos:e,origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==k,is_foreign:!i.data.origin})),!v){k&&k.last_error&&(d=k.last_error());break}return"i"===e&&l.parent().is(".jstree-closed")&&k.settings.dnd.open_timeout&&(!i.event||"dragover"!==i.event.type||j)&&(f&&clearTimeout(f),f=setTimeout(function(a,b){return function(){a.open_node(b)}}(k,l),k.settings.dnd.open_timeout)),v?(E=k.get_node(s,!0),E.hasClass(".jstree-dnd-parent")||(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),E.addClass("jstree-dnd-parent")),c={ins:k,par:s,pos:"i"!==e||"last"!==B||0!==t||k.is_loaded(C)?t:"last"},g.css({left:p+"px",top:q+"px"}).show(),g.removeClass("jstree-above jstree-inside jstree-below").addClass(F),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=D?"copy":"move"),d={},u=!0,!1):void 0}),u===!0))return}else{for(v=!0,w=0,x=i.data.nodes.length;x>w;w++)if(v=v&&k.check(i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",i.data.origin&&i.data.origin!==k?i.data.origin.get_node(i.data.nodes[w]):i.data.nodes[w],a.jstree.root,"last",{dnd:!0,ref:k.get_node(a.jstree.root),pos:"i",origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==k,is_foreign:!i.data.origin}),!v)break;if(v)return c={ins:k,par:a.jstree.root,pos:"last"},g.hide(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),void(i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=D?"copy":"move"))}a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),c=!1,i.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),i.event.originalEvent&&i.event.originalEvent.dataTransfer,g.hide()}}).on("dnd_scroll.vakata.jstree",function(a,b){b&&b.data&&b.data.jstree&&(g.hide(),c=!1,e=!1,b.helper.find(".jstree-icon").first().removeClass("jstree-ok").addClass("jstree-er"))}).on("dnd_stop.vakata.jstree",function(b,h){if(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),f&&clearTimeout(f),h&&h.data&&h.data.jstree){g.hide().detach();var i,j,k=[];if(c){for(i=0,j=h.data.nodes.length;j>i;i++)k[i]=h.data.origin?h.data.origin.get_node(h.data.nodes[i]):h.data.nodes[i];c.ins[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(h.event.metaKey||h.event.ctrlKey))?"copy_node":"move_node"](k,c.par,c.pos,!1,!1,!1,h.data.origin)}else i=a(h.event.target).closest(".jstree"),i.length&&d&&d.error&&"check"===d.error&&(i=i.jstree(!0),i&&i.settings.core.error.call(this,d));e=!1,c=!1}}).on("keyup.jstree keydown.jstree",function(b,h){h=a.vakata.dnd._get(),h&&h.data&&h.data.jstree&&("keyup"===b.type&&27===b.which?(f&&clearTimeout(f),c=!1,d=!1,e=!1,f=!1,g.hide().detach(),a.vakata.dnd._clean()):(h.helper.find(".jstree-copy").first()[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(b.metaKey||b.ctrlKey))?"show":"hide"](),e&&(e.metaKey=b.metaKey,e.ctrlKey=b.ctrlKey,a.vakata.dnd._trigger("move",e))))})}),function(a){a.vakata.html={div:a("
        "),escape:function(b){return a.vakata.html.div.text(b).html()},strip:function(b){return a.vakata.html.div.empty().append(a.parseHTML(b)).text()}};var c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1};a.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:10},_trigger:function(c,d,e){e===b&&(e=a.vakata.dnd._get()),e.event=d,a(i).triggerHandler("dnd_"+c+".vakata",e)},_get:function(){return{data:c.data,element:c.element,helper:c.helper}},_clean:function(){c.helper&&c.helper.remove(),c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},n=null,a(i).off("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).off("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop)},_scroll:function(b){if(!c.scroll_e||!c.scroll_l&&!c.scroll_t)return c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),!1;if(!c.scroll_i)return c.scroll_i=setInterval(a.vakata.dnd._scroll,100),!1;if(b===!0)return!1;var d=c.scroll_e.scrollTop(),e=c.scroll_e.scrollLeft();c.scroll_e.scrollTop(d+c.scroll_t*a.vakata.dnd.settings.scroll_speed),c.scroll_e.scrollLeft(e+c.scroll_l*a.vakata.dnd.settings.scroll_speed),(d!==c.scroll_e.scrollTop()||e!==c.scroll_e.scrollLeft())&&a.vakata.dnd._trigger("scroll",c.scroll_e)},start:function(b,d,e){"touchstart"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag&&a.vakata.dnd.stop({});try{b.currentTarget.unselectable="on",b.currentTarget.onselectstart=function(){return!1},b.currentTarget.style&&(b.currentTarget.style.touchAction="none",b.currentTarget.style.msTouchAction="none",b.currentTarget.style.MozUserSelect="none")}catch(f){}return c.init_x=b.pageX,c.init_y=b.pageY,c.data=d,c.is_down=!0,c.element=b.currentTarget,c.target=b.target,c.is_touch="touchstart"===b.type,e!==!1&&(c.helper=a("
        ").html(e).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),a(i).on("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).on("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop),!1},drag:function(b){if("touchmove"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_down){if(!c.is_drag){if(!(Math.abs(b.pageX-c.init_x)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)||Math.abs(b.pageY-c.init_y)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)))return;c.helper&&(c.helper.appendTo(i.body),c.helper_w=c.helper.outerWidth()),c.is_drag=!0,a(c.target).one("click.vakata",!1),a.vakata.dnd._trigger("start",b)}var d=!1,e=!1,f=!1,g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n=!1;return c.scroll_t=0,c.scroll_l=0,c.scroll_e=!1,a(a(b.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return/^auto|scroll$/.test(a(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var d=a(this),e=d.offset();return this.scrollHeight>this.offsetHeight&&(e.top+d.height()-b.pageYthis.offsetWidth&&(e.left+d.width()-b.pageXg&&b.pageY-kg&&g-(b.pageY-k)j&&b.pageX-lj&&j-(b.pageX-l)f&&(m=f-50),h&&n+c.helper_w>h&&(n=h-(c.helper_w+2)),c.helper.css({left:n+"px",top:m+"px"})),a.vakata.dnd._trigger("move",b),!1}},stop:function(b){if("touchend"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag)b.target!==c.target&&a(c.target).off("click.vakata"),a.vakata.dnd._trigger("stop",b);else if("touchend"===b.type&&b.target===c.target){var d=setTimeout(function(){a(b.target).click()},100);a(b.target).one("click",function(){d&&clearTimeout(d)})}return a.vakata.dnd._clean(),!1}}}(a),a.jstree.defaults.massload=null,a.jstree.plugins.massload=function(b,c){this.init=function(a,b){this._data.massload={},c.init.call(this,a,b)},this._load_nodes=function(b,d,e,f){var g=this.settings.massload,h=[],i=this._model.data,j,k,l;if(!e){for(j=0,k=b.length;k>j;j++)(!i[b[j]]||!i[b[j]].state.loaded&&!i[b[j]].state.failed||f)&&(h.push(b[j]),l=this.get_node(b[j],!0),l&&l.length&&l.addClass("jstree-loading").attr("aria-busy",!0));if(this._data.massload={},h.length){if(a.isFunction(g))return g.call(this,h,a.proxy(function(a){var g,h;if(a)for(g in a)a.hasOwnProperty(g)&&(this._data.massload[g]=a[g]);for(g=0,h=b.length;h>g;g++)l=this.get_node(b[g],!0),l&&l.length&&l.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this));if("object"==typeof g&&g&&g.url)return g=a.extend(!0,{},g),a.isFunction(g.url)&&(g.url=g.url.call(this,h)),a.isFunction(g.data)&&(g.data=g.data.call(this,h)),a.ajax(g).done(a.proxy(function(a,g,h){var i,j;if(a)for(i in a)a.hasOwnProperty(i)&&(this._data.massload[i]=a[i]);for(i=0,j=b.length;j>i;i++)l=this.get_node(b[i],!0),l&&l.length&&l.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this)).fail(a.proxy(function(a){c._load_nodes.call(this,b,d,e,f)},this))}}return c._load_nodes.call(this,b,d,e,f)},this._load_node=function(b,d){var e=this._data.massload[b.id],f=null,g;return e?(f=this["string"==typeof e?"_append_html_data":"_append_json_data"](b,"string"==typeof e?a(a.parseHTML(e)).filter(function(){return 3!==this.nodeType}):e,function(a){d.call(this,a)}),g=this.get_node(b.id,!0),g&&g.length&&g.removeClass("jstree-loading").attr("aria-busy",!1),delete this._data.massload[b.id],f):c._load_node.call(this,b,d)}},a.jstree.defaults.search={ajax:!1,fuzzy:!1,case_sensitive:!1,show_only_matches:!1,show_only_matches_children:!1,close_opened_onclear:!0,search_leaves_only:!1,search_callback:!1},a.jstree.plugins.search=function(c,d){this.bind=function(){d.bind.call(this),this._data.search.str="",this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=!1,this._data.search.smc=!1,this._data.search.hdn=[],this.element.on("search.jstree",a.proxy(function(b,c){if(this._data.search.som&&c.res.length){var d=this._model.data,e,f,g=[],h,i;for(e=0,f=c.res.length;f>e;e++)if(d[c.res[e]]&&!d[c.res[e]].state.hidden&&(g.push(c.res[e]),g=g.concat(d[c.res[e]].parents),this._data.search.smc))for(h=0,i=d[c.res[e]].children_d.length;i>h;h++)d[d[c.res[e]].children_d[h]]&&!d[d[c.res[e]].children_d[h]].state.hidden&&g.push(d[c.res[e]].children_d[h]);g=a.vakata.array_remove_item(a.vakata.array_unique(g),a.jstree.root),this._data.search.hdn=this.hide_all(!0),this.show_node(g,!0),this.redraw(!0)}},this)).on("clear_search.jstree",a.proxy(function(a,b){this._data.search.som&&b.res.length&&(this.show_node(this._data.search.hdn,!0),this.redraw(!0))},this))},this.search=function(c,d,e,f,g,h){if(c===!1||""===a.trim(c.toString()))return this.clear_search();f=this.get_node(f),f=f&&f.id?f.id:null,c=c.toString();var i=this.settings.search,j=i.ajax?i.ajax:!1,k=this._model.data,l=null,m=[],n=[],o,p;if(this._data.search.res.length&&!g&&this.clear_search(),e===b&&(e=i.show_only_matches),h===b&&(h=i.show_only_matches_children),!d&&j!==!1)return a.isFunction(j)?j.call(this,c,a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this),f):(j=a.extend({},j),j.data||(j.data={}),j.data.str=c,f&&(j.data.inside=f),this._data.search.lastRequest&&this._data.search.lastRequest.abort(),this._data.search.lastRequest=a.ajax(j).fail(a.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(j)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this)),this._data.search.lastRequest);if(g||(this._data.search.str=c,this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=e,this._data.search.smc=h),l=new a.vakata.search(c,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),a.each(k[f?f:a.jstree.root].children_d,function(a,b){var d=k[b];d.text&&!d.state.hidden&&(!i.search_leaves_only||d.state.loaded&&0===d.children.length)&&(i.search_callback&&i.search_callback.call(this,c,d)||!i.search_callback&&l.search(d.text).isMatch)&&(m.push(b),n=n.concat(d.parents))}),m.length){for(n=a.vakata.array_unique(n),o=0,p=n.length;p>o;o++)n[o]!==a.jstree.root&&k[n[o]]&&this.open_node(n[o],null,0)===!0&&this._data.search.opn.push(n[o]);g?(this._data.search.dom=this._data.search.dom.add(a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #")))),this._data.search.res=a.vakata.array_unique(this._data.search.res.concat(m))):(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.res=m),this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:c,res:this._data.search.res,show_only_matches:e})},this.clear_search=function(){this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.res.length&&(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(this._data.search.res,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search")),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=a()},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments),b&&-1!==a.inArray(b.id,this._data.search.res)){var g,h,i=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(i.className+=" jstree-search")}return b}},function(a){a.vakata.search=function(b,c,d){d=d||{},d=a.extend({},a.vakata.search.defaults,d),d.fuzzy!==!1&&(d.fuzzy=!0),b=d.caseSensitive?b:b.toLowerCase();var e=d.location,f=d.distance,g=d.threshold,h=b.length,i,j,k,l;return h>32&&(d.fuzzy=!1),d.fuzzy&&(i=1<c;c++)a[b.charAt(c)]=0;for(c=0;h>c;c++)a[b.charAt(c)]|=1<c;c++){o=0,p=q;while(p>o)k(c,e+p)<=m?o=p:q=p,p=Math.floor((q-o)/2+o);for(q=p,s=Math.max(1,e-p+1),t=Math.min(e+p,l)+h,u=new Array(t+2),u[t+1]=(1<=s;f--)if(v=j[a.charAt(f-1)],0===c?u[f]=(u[f+1]<<1|1)&v:u[f]=(u[f+1]<<1|1)&v|((r[f+1]|r[f])<<1|1)|r[f+1],u[f]&i&&(w=k(c,f-1),m>=w)){if(m=w,n=f-1,x.push(n),!(n>e))break;s=Math.max(1,2*e-n)}if(k(c+1,e)>m)break;r=u}return{isMatch:n>=0,score:w}},c===!0?{search:l}:l(c)},a.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1}}(a),a.jstree.defaults.sort=function(a,b){return this.get_text(a)>this.get_text(b)?1:-1},a.jstree.plugins.sort=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("model.jstree",a.proxy(function(a,b){this.sort(b.parent,!0)},this)).on("rename_node.jstree create_node.jstree",a.proxy(function(a,b){this.sort(b.parent||b.node.parent,!1),this.redraw_node(b.parent||b.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",a.proxy(function(a,b){this.sort(b.parent,!1),this.redraw_node(b.parent,!0)},this))},this.sort=function(b,c){var d,e;if(b=this.get_node(b),b&&b.children&&b.children.length&&(b.children.sort(a.proxy(this.settings.sort,this)),c))for(d=0,e=b.children_d.length;e>d;d++)this.sort(b.children_d[d],!1)}};var o=!1;a.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree",ttl:!1,filter:!1,preserve_loaded:!1},a.jstree.plugins.state=function(b,c){this.bind=function(){c.bind.call(this);var b=a.proxy(function(){this.element.on(this.settings.state.events,a.proxy(function(){o&&clearTimeout(o),o=setTimeout(a.proxy(function(){this.save_state()},this),100)},this)),this.trigger("state_ready")},this);this.element.on("ready.jstree",a.proxy(function(a,c){this.element.one("restore_state.jstree",b),this.restore_state()||b()},this))},this.save_state=function(){var b=this.get_state();this.settings.state.preserve_loaded||delete b.core.loaded;var c={state:b,ttl:this.settings.state.ttl,sec:+new Date};a.vakata.storage.set(this.settings.state.key,JSON.stringify(c))},this.restore_state=function(){var b=a.vakata.storage.get(this.settings.state.key);if(b)try{b=JSON.parse(b)}catch(c){return!1}return b&&b.ttl&&b.sec&&+new Date-b.sec>b.ttl?!1:(b&&b.state&&(b=b.state),b&&a.isFunction(this.settings.state.filter)&&(b=this.settings.state.filter.call(this,b)),b?(this.settings.state.preserve_loaded||delete b.core.loaded,this.element.one("set_state.jstree",function(c,d){d.instance.trigger("restore_state",{state:a.extend(!0,{},b)})}),this.set_state(b),!0):!1)},this.clear_state=function(){return a.vakata.storage.del(this.settings.state.key)}},function(a,b){a.vakata.storage={set:function(a,b){return window.localStorage.setItem(a,b)},get:function(a){return window.localStorage.getItem(a)},del:function(a){return window.localStorage.removeItem(a)}}}(a),a.jstree.defaults.types={"default":{}},a.jstree.defaults.types[a.jstree.root]={},a.jstree.plugins.types=function(c,d){this.init=function(c,e){var f,g;if(e&&e.types&&e.types["default"])for(f in e.types)if("default"!==f&&f!==a.jstree.root&&e.types.hasOwnProperty(f))for(g in e.types["default"])e.types["default"].hasOwnProperty(g)&&e.types[f][g]===b&&(e.types[f][g]=e.types["default"][g]);d.init.call(this,c,e),this._model.data[a.jstree.root].type=a.jstree.root},this.refresh=function(b,c){d.refresh.call(this,b,c),this._model.data[a.jstree.root].type=a.jstree.root},this.bind=function(){this.element.on("model.jstree",a.proxy(function(c,d){var e=this._model.data,f=d.nodes,g=this.settings.types,h,i,j="default",k;for(h=0,i=f.length;i>h;h++){if(j="default",e[f[h]].original&&e[f[h]].original.type&&g[e[f[h]].original.type]&&(j=e[f[h]].original.type),e[f[h]].data&&e[f[h]].data.jstree&&e[f[h]].data.jstree.type&&g[e[f[h]].data.jstree.type]&&(j=e[f[h]].data.jstree.type), +e[f[h]].type=j,e[f[h]].icon===!0&&g[j].icon!==b&&(e[f[h]].icon=g[j].icon),g[j].li_attr!==b&&"object"==typeof g[j].li_attr)for(k in g[j].li_attr)if(g[j].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].li_attr[k]===b?e[f[h]].li_attr[k]=g[j].li_attr[k]:"class"===k&&(e[f[h]].li_attr["class"]=g[j].li_attr["class"]+" "+e[f[h]].li_attr["class"])}if(g[j].a_attr!==b&&"object"==typeof g[j].a_attr)for(k in g[j].a_attr)if(g[j].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].a_attr[k]===b?e[f[h]].a_attr[k]=g[j].a_attr[k]:"href"===k&&"#"===e[f[h]].a_attr[k]?e[f[h]].a_attr.href=g[j].a_attr.href:"class"===k&&(e[f[h]].a_attr["class"]=g[j].a_attr["class"]+" "+e[f[h]].a_attr["class"])}}e[a.jstree.root].type=a.jstree.root},this)),d.bind.call(this)},this.get_json=function(b,c,e){var f,g,h=this._model.data,i=c?a.extend(!0,{},c,{no_id:!1}):{},j=d.get_json.call(this,b,i,e);if(j===!1)return!1;if(a.isArray(j))for(f=0,g=j.length;g>f;f++)j[f].type=j[f].id&&h[j[f].id]&&h[j[f].id].type?h[j[f].id].type:"default",c&&c.no_id&&(delete j[f].id,j[f].li_attr&&j[f].li_attr.id&&delete j[f].li_attr.id,j[f].a_attr&&j[f].a_attr.id&&delete j[f].a_attr.id);else j.type=j.id&&h[j.id]&&h[j.id].type?h[j.id].type:"default",c&&c.no_id&&(j=this._delete_ids(j));return j},this._delete_ids=function(b){if(a.isArray(b)){for(var c=0,d=b.length;d>c;c++)b[c]=this._delete_ids(b[c]);return b}return delete b.id,b.li_attr&&b.li_attr.id&&delete b.li_attr.id,b.a_attr&&b.a_attr.id&&delete b.a_attr.id,b.children&&a.isArray(b.children)&&(b.children=this._delete_ids(b.children)),b},this.check=function(c,e,f,g,h){if(d.check.call(this,c,e,f,g,h)===!1)return!1;e=e&&e.id?e:this.get_node(e),f=f&&f.id?f:this.get_node(f);var i=e&&e.id?h&&h.origin?h.origin:a.jstree.reference(e.id):null,j,k,l,m;switch(i=i&&i._model&&i._model.data?i._model.data:null,c){case"create_node":case"move_node":case"copy_node":if("move_node"!==c||-1===a.inArray(e.id,f.children)){if(j=this.get_rules(f),j.max_children!==b&&-1!==j.max_children&&j.max_children===f.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(j.valid_children!==b&&-1!==j.valid_children&&-1===a.inArray(e.type||"default",j.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(i&&e.children_d&&e.parents){for(k=0,l=0,m=e.children_d.length;m>l;l++)k=Math.max(k,i[e.children_d[l]].parents.length);k=k-e.parents.length+1}(0>=k||k===b)&&(k=1);do{if(j.max_depth!==b&&-1!==j.max_depth&&j.max_depthg;g++)this.set_type(c[g],d);return!0}if(f=this.settings.types,c=this.get_node(c),!f[d]||!c)return!1;if(l=this.get_node(c,!0),l&&l.length&&(m=l.children(".jstree-anchor")),i=c.type,j=this.get_icon(c),c.type=d,(j===!0||!f[i]||f[i].icon!==b&&j===f[i].icon)&&this.set_icon(c,f[d].icon!==b?f[d].icon:!0),f[i]&&f[i].li_attr!==b&&"object"==typeof f[i].li_attr)for(k in f[i].li_attr)if(f[i].li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].li_attr["class"]=(e[c.id].li_attr["class"]||"").replace(f[i].li_attr[k],""),l&&l.removeClass(f[i].li_attr[k])):e[c.id].li_attr[k]===f[i].li_attr[k]&&(e[c.id].li_attr[k]=null,l&&l.removeAttr(k))}if(f[i]&&f[i].a_attr!==b&&"object"==typeof f[i].a_attr)for(k in f[i].a_attr)if(f[i].a_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].a_attr["class"]=(e[c.id].a_attr["class"]||"").replace(f[i].a_attr[k],""),m&&m.removeClass(f[i].a_attr[k])):e[c.id].a_attr[k]===f[i].a_attr[k]&&("href"===k?(e[c.id].a_attr[k]="#",m&&m.attr("href","#")):(delete e[c.id].a_attr[k],m&&m.removeAttr(k)))}if(f[d].li_attr!==b&&"object"==typeof f[d].li_attr)for(k in f[d].li_attr)if(f[d].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].li_attr[k]===b?(e[c.id].li_attr[k]=f[d].li_attr[k],l&&("class"===k?l.addClass(f[d].li_attr[k]):l.attr(k,f[d].li_attr[k]))):"class"===k&&(e[c.id].li_attr["class"]=f[d].li_attr[k]+" "+e[c.id].li_attr["class"],l&&l.addClass(f[d].li_attr[k]))}if(f[d].a_attr!==b&&"object"==typeof f[d].a_attr)for(k in f[d].a_attr)if(f[d].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].a_attr[k]===b?(e[c.id].a_attr[k]=f[d].a_attr[k],m&&("class"===k?m.addClass(f[d].a_attr[k]):m.attr(k,f[d].a_attr[k]))):"href"===k&&"#"===e[c.id].a_attr[k]?(e[c.id].a_attr.href=f[d].a_attr.href,m&&m.attr("href",f[d].a_attr.href)):"class"===k&&(e[c.id].a_attr["class"]=f[d].a_attr["class"]+" "+e[c.id].a_attr["class"],m&&m.addClass(f[d].a_attr[k]))}return!0}},a.jstree.defaults.unique={case_sensitive:!1,trim_whitespace:!1,duplicate:function(a,b){return a+" ("+b+")"}},a.jstree.plugins.unique=function(c,d){this.check=function(b,c,e,f,g){if(d.check.call(this,b,c,e,f,g)===!1)return!1;if(c=c&&c.id?c:this.get_node(c),e=e&&e.id?e:this.get_node(e),!e||!e.children)return!0;var h="rename_node"===b?f:c.text,i=[],j=this.settings.unique.case_sensitive,k=this.settings.unique.trim_whitespace,l=this._model.data,m,n,o;for(m=0,n=e.children.length;n>m;m++)o=l[e.children[m]].text,j||(o=o.toLowerCase()),k&&(o=o.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),i.push(o);switch(j||(h=h.toLowerCase()),k&&(h=h.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),b){case"delete_node":return!0;case"rename_node":return o=c.text||"",j||(o=o.toLowerCase()),k&&(o=o.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),m=-1===a.inArray(h,i)||c.text&&o===h,m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"create_node":return m=-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_04",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"copy_node":return m=-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_02",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"move_node":return m=c.parent===e.id&&(!g||!g.is_multi)||-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_03",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m}return!0},this.create_node=function(c,e,f,g,h){if(!e||e.text===b){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return d.create_node.call(this,c,e,f,g,h);if(f=f===b?"last":f,!f.toString().match(/^(before|after)$/)&&!h&&!this.is_loaded(c))return d.create_node.call(this,c,e,f,g,h);e||(e={});var i,j,k,l,m,n=this._model.data,o=this.settings.unique.case_sensitive,p=this.settings.unique.trim_whitespace,q=this.settings.unique.duplicate,r;for(j=i=this.get_string("New node"),k=[],l=0,m=c.children.length;m>l;l++)r=n[c.children[l]].text,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),k.push(r);l=1,r=j,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""));while(-1!==a.inArray(r,k))j=q.call(this,i,++l).toString(),r=j,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""));e.text=j}return d.create_node.call(this,c,e,f,g,h)}};var p=i.createElement("DIV");if(p.setAttribute("unselectable","on"),p.setAttribute("role","presentation"),p.className="jstree-wholerow",p.innerHTML=" ",a.jstree.plugins.wholerow=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("ready.jstree set_state.jstree",a.proxy(function(){this.hide_dots()},this)).on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var c=!1,d,e;for(d=0,e=b.selected.length;e>d;d++)c=this.get_node(b.selected[d],!0),c&&c.length&&c.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",a.proxy(function(a,b){this.get_node(b.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",a.proxy(function(a,b){"hover_node"===a.type&&this.is_disabled(b.node)||this.get_node(b.node,!0).children(".jstree-wholerow")["hover_node"===a.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",a.proxy(function(b){if(this._data.contextmenu){b.preventDefault();var c=a.Event("contextmenu",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey,pageX:b.pageX,pageY:b.pageY});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c)}},this)).on("click.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("dblclick.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("dblclick",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",a.proxy(function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",a.proxy(function(a){return a.stopImmediatePropagation(),this.is_disabled(a.currentTarget)||this.hover_node(a.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),c.teardown.call(this)},this.redraw_node=function(b,d,e,f){if(b=c.redraw_node.apply(this,arguments)){var g=p.cloneNode(!0);-1!==a.inArray(b.id,this._data.core.selected)&&(g.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===b.id&&(g.className+=" jstree-wholerow-hovered"),b.insertBefore(g,b.childNodes[0])}return b}},window.customElements&&Object&&Object.create){var q=Object.create(HTMLElement.prototype);q.createdCallback=function(){var b={core:{},plugins:[]},c;for(c in a.jstree.plugins)a.jstree.plugins.hasOwnProperty(c)&&this.attributes[c]&&(b.plugins.push(c),this.getAttribute(c)&&JSON.parse(this.getAttribute(c))&&(b[c]=JSON.parse(this.getAttribute(c))));for(c in a.jstree.defaults.core)a.jstree.defaults.core.hasOwnProperty(c)&&this.attributes[c]&&(b.core[c]=JSON.parse(this.getAttribute(c))||this.getAttribute(c));a(this).jstree(b)};try{window.customElements.define("vakata-jstree",function(){},{prototype:q})}catch(r){}}}}); \ No newline at end of file diff --git a/web/help/vendors/jstree-3.3.10/themes/default-dark/32px.png b/web/help/vendors/jstree-3.3.10/themes/default-dark/32px.png new file mode 100644 index 00000000..60395729 Binary files /dev/null and b/web/help/vendors/jstree-3.3.10/themes/default-dark/32px.png differ diff --git a/web/help/vendors/jstree-3.3.10/themes/default-dark/40px.png b/web/help/vendors/jstree-3.3.10/themes/default-dark/40px.png new file mode 100644 index 00000000..aae89ad3 Binary files /dev/null and b/web/help/vendors/jstree-3.3.10/themes/default-dark/40px.png differ diff --git a/web/help/vendors/jstree-3.3.10/themes/default-dark/style.css b/web/help/vendors/jstree-3.3.10/themes/default-dark/style.css new file mode 100644 index 00000000..d8dc188f --- /dev/null +++ b/web/help/vendors/jstree-3.3.10/themes/default-dark/style.css @@ -0,0 +1,1146 @@ +/* jsTree default dark theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.jstree-contextmenu .jstree-anchor { + -webkit-user-select: none; + /* disable selection/Copy of UIWebView */ + -webkit-touch-callout: none; + /* disable the IOS popup when long-press on a link */ +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context .vakata-contextmenu-disabled > a > i { + filter: grayscale(100%); +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default-dark .jstree-anchor, +.jstree-default-dark .jstree-animated, +.jstree-default-dark .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default-dark .jstree-hovered { + background: #555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555; +} +.jstree-default-dark .jstree-context { + background: #555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555; +} +.jstree-default-dark .jstree-clicked { + background: #5fa2db; + border-radius: 2px; + box-shadow: inset 0 0 1px #666666; +} +.jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default-dark .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #333333; +} +.jstree-default-dark .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark .jstree-search { + font-style: italic; + color: #ffffff; + font-weight: bold; +} +.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #555; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #555; +} +.jstree-default-dark > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, +.jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default-dark .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default-dark .jstree-wholerow-hovered { + background: #555; +} +.jstree-default-dark .jstree-wholerow-clicked { + background: #5fa2db; + background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); + background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); +} +.jstree-default-dark .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default-dark .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default-dark .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default-dark .jstree-wholerow { + height: 24px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default-dark .jstree-last { + background: transparent; +} +.jstree-default-dark .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default-dark .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default-dark .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default-dark .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-node, +.jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default-dark .jstree-disabled { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default-dark .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default-dark .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark > .jstree-striped { + background-size: auto 48px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default-dark .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default-dark .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default-dark > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark .jstree-ok, +#jstree-dnd.jstree-default-dark .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default-dark .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default-dark .jstree-er { + background-position: -36px -68px; +} +.jstree-default-dark .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-dark-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-dark-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-dark-small .jstree-wholerow { + height: 18px; +} +.jstree-default-dark-small .jstree-node, +.jstree-default-dark-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-dark-small .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-dark-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-dark-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-dark-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-node, +.jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-dark-small .jstree-disabled { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-dark-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-dark-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-dark-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-dark-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-dark-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok, +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-dark-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-dark-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-dark-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-dark-large .jstree-wholerow { + height: 32px; +} +.jstree-default-dark-large .jstree-node, +.jstree-default-dark-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-dark-large .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-dark-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-dark-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-dark-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-node, +.jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-dark-large .jstree-disabled { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-dark-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-dark-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-dark-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-dark-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-dark-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok, +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-dark-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-dark-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-dark-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-dark-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-dark-responsive .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-open > .jstree-ocl { + background-position: 0 0 !important; + } + .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0 !important; + } + .jstree-default-dark-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-dark-responsive .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-dark-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-dark-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-dark-responsive .jstree-wholerow { + border-top: 1px solid #666; + border-bottom: 1px solid #000; + background: #333333; + height: 40px; + } + .jstree-default-dark-responsive .jstree-wholerow-hovered { + background: #555; + } + .jstree-default-dark-responsive .jstree-wholerow-clicked { + background: #5fa2db; + } + .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #111111; + } + .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #111111; + border-top: 0; + } + .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-node > .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-dark-responsive .jstree-last { + background: transparent; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-dark-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-dark-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-dark-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} +.jstree-default-dark { + background: #333; +} +.jstree-default-dark .jstree-anchor { + color: #999; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); +} +.jstree-default-dark .jstree-clicked, +.jstree-default-dark .jstree-checked { + color: white; +} +.jstree-default-dark .jstree-hovered { + color: white; +} +#jstree-marker.jstree-default-dark { + border-left-color: #999; + background: transparent; +} +.jstree-default-dark .jstree-anchor > .jstree-icon { + opacity: 0.75; +} +.jstree-default-dark .jstree-clicked > .jstree-icon, +.jstree-default-dark .jstree-hovered > .jstree-icon, +.jstree-default-dark .jstree-checked > .jstree-icon { + opacity: 1; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} diff --git a/web/help/vendors/jstree-3.3.10/themes/default-dark/style.min.css b/web/help/vendors/jstree-3.3.10/themes/default-dark/style.min.css new file mode 100644 index 00000000..fb1d236f --- /dev/null +++ b/web/help/vendors/jstree-3.3.10/themes/default-dark/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default-dark .jstree-anchor,.jstree-default-dark .jstree-animated,.jstree-default-dark .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default-dark .jstree-hovered{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-context{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-clicked{background:#5fa2db;border-radius:2px;box-shadow:inset 0 0 1px #666666}.jstree-default-dark .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default-dark .jstree-disabled{background:transparent;color:#666666}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#333333}.jstree-default-dark .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark .jstree-search{font-style:italic;color:#ffffff;font-weight:bold}.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#555}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#555}.jstree-default-dark>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default-dark>.jstree-wholerow-ul .jstree-hovered,.jstree-default-dark>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default-dark .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default-dark .jstree-wholerow-hovered{background:#555}.jstree-default-dark .jstree-wholerow-clicked{background:#5fa2db;background:-webkit-linear-gradient(top, #5fa2db 0, #5fa2db 100%);background:linear-gradient(to bottom, #5fa2db 0, #5fa2db 100%)}.jstree-default-dark .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default-dark .jstree-anchor{line-height:24px;height:24px}.jstree-default-dark .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default-dark .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default-dark.jstree-rtl .jstree-node{margin-right:24px}.jstree-default-dark .jstree-wholerow{height:24px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-image:url("32px.png")}.jstree-default-dark .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default-dark .jstree-last{background:transparent}.jstree-default-dark .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default-dark .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default-dark .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default-dark .jstree-themeicon{background-position:-260px -4px}.jstree-default-dark>.jstree-no-dots .jstree-node,.jstree-default-dark>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default-dark>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default-dark .jstree-disabled{background:transparent}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark .jstree-checkbox{background-position:-164px -4px}.jstree-default-dark .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default-dark .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default-dark .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default-dark .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark>.jstree-striped{background-size:auto 48px}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default-dark.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default-dark.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default-dark .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default-dark .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default-dark>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default-dark .jstree-ok,#jstree-dnd.jstree-default-dark .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default-dark .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default-dark .jstree-er{background-position:-36px -68px}.jstree-default-dark .jstree-ellipsis{overflow:hidden}.jstree-default-dark .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-dark-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-dark-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-dark-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-dark-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-dark-small .jstree-wholerow{height:18px}.jstree-default-dark-small .jstree-node,.jstree-default-dark-small .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-dark-small .jstree-last{background:transparent}.jstree-default-dark-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-dark-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-dark-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-dark-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-node,.jstree-default-dark-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-dark-small .jstree-disabled{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-dark-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-dark-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-small>.jstree-striped{background-size:auto 36px}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-dark-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-dark-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-dark-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-dark-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-dark-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-dark-small .jstree-ok,#jstree-dnd.jstree-default-dark-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-dark-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-dark-small .jstree-er{background-position:-39px -71px}.jstree-default-dark-small .jstree-ellipsis{overflow:hidden}.jstree-default-dark-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-dark-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-dark-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-dark-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-dark-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-dark-large .jstree-wholerow{height:32px}.jstree-default-dark-large .jstree-node,.jstree-default-dark-large .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-dark-large .jstree-last{background:transparent}.jstree-default-dark-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-dark-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-dark-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-dark-large .jstree-themeicon{background-position:-256px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-node,.jstree-default-dark-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-dark-large .jstree-disabled{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-large .jstree-checkbox{background-position:-160px 0}.jstree-default-dark-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-dark-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-large>.jstree-striped{background-size:auto 64px}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-dark-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-dark-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-dark-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-dark-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-dark-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-dark-large .jstree-ok,#jstree-dnd.jstree-default-dark-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-dark-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-dark-large .jstree-er{background-position:-32px -64px}.jstree-default-dark-large .jstree-ellipsis{overflow:hidden}.jstree-default-dark-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-dark-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-dark-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-dark-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-dark-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-dark-responsive .jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl,.jstree-default-dark-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-dark-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-dark-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-dark-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-dark-responsive .jstree-checkbox,.jstree-default-dark-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-dark-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-dark-responsive>.jstree-striped{background:transparent}.jstree-default-dark-responsive .jstree-wholerow{border-top:1px solid #666;border-bottom:1px solid #000;background:#333333;height:40px}.jstree-default-dark-responsive .jstree-wholerow-hovered{background:#555}.jstree-default-dark-responsive .jstree-wholerow-clicked{background:#5fa2db}.jstree-default-dark-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #111111}.jstree-default-dark-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #111111;border-top:0}.jstree-default-dark-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-node>.jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-dark-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-dark-responsive .jstree-last{background:transparent}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-dark-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-dark-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}.jstree-default-dark{background:#333}.jstree-default-dark .jstree-anchor{color:#999;text-shadow:1px 1px 0 rgba(0,0,0,0.5)}.jstree-default-dark .jstree-clicked,.jstree-default-dark .jstree-checked{color:white}.jstree-default-dark .jstree-hovered{color:white}#jstree-marker.jstree-default-dark{border-left-color:#999;background:transparent}.jstree-default-dark .jstree-anchor>.jstree-icon{opacity:.75}.jstree-default-dark .jstree-clicked>.jstree-icon,.jstree-default-dark .jstree-hovered>.jstree-icon,.jstree-default-dark .jstree-checked>.jstree-icon{opacity:1}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent} \ No newline at end of file diff --git a/web/help/vendors/jstree-3.3.10/themes/default-dark/throbber.gif b/web/help/vendors/jstree-3.3.10/themes/default-dark/throbber.gif new file mode 100644 index 00000000..169062cd Binary files /dev/null and b/web/help/vendors/jstree-3.3.10/themes/default-dark/throbber.gif differ diff --git a/web/help/vendors/jstree-3.3.10/themes/default/32px.png b/web/help/vendors/jstree-3.3.10/themes/default/32px.png new file mode 100644 index 00000000..ca6af206 Binary files /dev/null and b/web/help/vendors/jstree-3.3.10/themes/default/32px.png differ diff --git a/web/help/vendors/jstree-3.3.10/themes/default/40px.png b/web/help/vendors/jstree-3.3.10/themes/default/40px.png new file mode 100644 index 00000000..2a3fcb9d Binary files /dev/null and b/web/help/vendors/jstree-3.3.10/themes/default/40px.png differ diff --git a/web/help/vendors/jstree-3.3.10/themes/default/style.css b/web/help/vendors/jstree-3.3.10/themes/default/style.css new file mode 100644 index 00000000..0703168b --- /dev/null +++ b/web/help/vendors/jstree-3.3.10/themes/default/style.css @@ -0,0 +1,1102 @@ +/* jsTree default theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.jstree-contextmenu .jstree-anchor { + -webkit-user-select: none; + /* disable selection/Copy of UIWebView */ + -webkit-touch-callout: none; + /* disable the IOS popup when long-press on a link */ +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context .vakata-contextmenu-disabled > a > i { + filter: grayscale(100%); +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default .jstree-anchor, +.jstree-default .jstree-animated, +.jstree-default .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default .jstree-hovered { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-context { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-clicked { + background: #beebff; + border-radius: 2px; + box-shadow: inset 0 0 1px #999999; +} +.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default .jstree-search { + font-style: italic; + color: #8b0000; + font-weight: bold; +} +.jstree-default .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #e7f4f9; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default > .jstree-wholerow-ul .jstree-hovered, +.jstree-default > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default .jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default .jstree-wholerow-clicked { + background: #beebff; + background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); + background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); +} +.jstree-default .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default .jstree-wholerow { + height: 24px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default .jstree-last { + background: transparent; +} +.jstree-default .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default > .jstree-no-dots .jstree-node, +.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default .jstree-disabled { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default > .jstree-striped { + background-size: auto 48px; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default .jstree-ok, +#jstree-dnd.jstree-default .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default .jstree-er { + background-position: -36px -68px; +} +.jstree-default .jstree-ellipsis { + overflow: hidden; +} +.jstree-default .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-small .jstree-wholerow { + height: 18px; +} +.jstree-default-small .jstree-node, +.jstree-default-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-small .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-node, +.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-small .jstree-disabled { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-small .jstree-ok, +#jstree-dnd.jstree-default-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-large .jstree-wholerow { + height: 32px; +} +.jstree-default-large .jstree-node, +.jstree-default-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-large .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-node, +.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-large .jstree-disabled { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-large .jstree-ok, +#jstree-dnd.jstree-default-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-responsive .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-open > .jstree-ocl { + background-position: 0 0 !important; + } + .jstree-default-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0 !important; + } + .jstree-default-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-responsive .jstree-checkbox, + .jstree-default-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-responsive .jstree-wholerow { + border-top: 1px solid rgba(255, 255, 255, 0.7); + border-bottom: 1px solid rgba(64, 64, 64, 0.2); + background: #ebebeb; + height: 40px; + } + .jstree-default-responsive .jstree-wholerow-hovered { + background: #e7f4f9; + } + .jstree-default-responsive .jstree-wholerow-clicked { + background: #beebff; + } + .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #666666; + } + .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #666666; + border-top: 0; + } + .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-node > .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-responsive .jstree-last { + background: transparent; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} diff --git a/web/help/vendors/jstree-3.3.10/themes/default/style.min.css b/web/help/vendors/jstree-3.3.10/themes/default/style.min.css new file mode 100644 index 00000000..93f80e91 --- /dev/null +++ b/web/help/vendors/jstree-3.3.10/themes/default/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:transparent}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:transparent}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:transparent}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:transparent}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file diff --git a/web/help/vendors/jstree-3.3.10/themes/default/throbber.gif b/web/help/vendors/jstree-3.3.10/themes/default/throbber.gif new file mode 100644 index 00000000..cf06c1ad Binary files /dev/null and b/web/help/vendors/jstree-3.3.10/themes/default/throbber.gif differ diff --git a/web/help/vendors/markjs-8.11.1/jquery.mark.min.js b/web/help/vendors/markjs-8.11.1/jquery.mark.min.js new file mode 100644 index 00000000..197e3123 --- /dev/null +++ b/web/help/vendors/markjs-8.11.1/jquery.mark.min.js @@ -0,0 +1,7 @@ +/*!*************************************************** +* mark.js v8.11.1 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):e.Mark=t(e.jQuery)}(this,function(e){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e;var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},r=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;n(this,e),this.ctx=t,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return r(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t=e.getAttribute("src").trim();return"about:blank"===e.contentWindow.location.href&&"about:blank"!==t&&t}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(function(t){return!r.call(e,t)||(i=!0,!1)}),i}return!1}}]),e}(),a=function(){function e(t){n(this,e),this.ctx=t,this.ie=!1;var r=window.navigator.userAgent;(r.indexOf("MSIE")>-1||r.indexOf("Trident")>-1)&&(this.ie=!0)}return r(e,[{key:"log",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":t(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+e)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynomyms(a)+"|"+this.processSynomyms(s)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(i){n.every(function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,i="";switch(("string"==typeof n?[]:n.limiters).forEach(function(e){i+="|"+t.escapeStr(e)}),r){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var i=t.callNoMatchOnInvalidRanges(e,r),o=i.start,a=i.end;i.valid&&(e.start=o,e.length=a-o,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,o=n.length,a=t-o,s=parseInt(e.start,10)-a;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return o.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),o=i.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=i.textContent,i.parentNode.replaceChild(a,i),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var o=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=o.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,i(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapMatches",value:function(e,t,n,r,i){var o=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[a];)if(n(i[a],t)){var s=i.index;if(0!==a)for(var c=1;c #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;bE;E++)if("0"===m[0]&&1E&&(m=k,E=z)):"0"===l[q]&&(p=!0,k=q,z=1);z>E&&(m=k,E=z);1=L&&D>>10&1023|55296),t=56320|t&1023);return D+=y(t)}).join("")}function E(n,t){return n+22+75*(26>n)-((0!=t)<<5)}function z(n,t,D){var x=0;n=D?g(n/700):n>>1;for(n+=g(n/t);455e&&(e=0);for(b=0;b=D&&w("invalid-input");var h=n.charCodeAt(e++); +h=10>h-48?h-22:26>h-65?h-65:26>h-97?h-97:36;(36<=h||h>g((2147483647-x)/f))&&w("overflow");x+=h*f;var A=c<=a?1:c>=a+26?26:c-a;if(hg(2147483647/h)&&w("overflow");f*=h}f=t.length+1;a=z(x-b,f,0==b);g(x/f)>2147483647-L&&w("overflow");L+=g(x/f);x%=f;t.splice(x++,0,L)}return q(t)}function p(n){var t,D,x,L=[];n=d(n);var a=n.length;var b=128;var c=0;var e=72;for(x=0;xf&&L.push(y(f))}for((t=D=L.length)&&L.push("-");t=b&& +fg((2147483647-c)/A)&&w("overflow");c+=(h-b)*A;b=h;for(x=0;x=e+26?26:h-e;if(J= 0x80 (not a basic code point)","invalid-input":"Invalid input"},g=Math.floor,y=String.fromCharCode,H;var G={version:"1.3.2",ucs2:{decode:d,encode:q},decode:k,encode:p,toASCII:function(n){return m(n,function(t){return u.test(t)?"xn--"+p(t):t})},toUnicode:function(n){return m(n,function(t){return F.test(t)?k(t.slice(4).toLowerCase()): +t})}};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return G});else if(B&&v)if(module.exports==B)v.exports=G;else for(H in G)G.hasOwnProperty(H)&&(B[H]=G[H]);else r.punycode=G})(this); +(function(r,w){"object"===typeof module&&module.exports?module.exports=w():"function"===typeof define&&define.amd?define(w):r.SecondLevelDomains=w(r)})(this,function(r){var w=r&&r.SecondLevelDomains,l={list:{ac:" com gov mil net org ",ae:" ac co gov mil name net org pro sch ",af:" com edu gov net org ",al:" com edu gov mil net org ",ao:" co ed gv it og pb ",ar:" com edu gob gov int mil net org tur ",at:" ac co gv or ",au:" asn com csiro edu gov id net org ",ba:" co com edu gov mil net org rs unbi unmo unsa untz unze ", +bb:" biz co com edu gov info net org store tv ",bh:" biz cc com edu gov info net org ",bn:" com edu gov net org ",bo:" com edu gob gov int mil net org tv ",br:" adm adv agr am arq art ato b bio blog bmd cim cng cnt com coop ecn edu eng esp etc eti far flog fm fnd fot fst g12 ggf gov imb ind inf jor jus lel mat med mil mus net nom not ntr odo org ppg pro psc psi qsl rec slg srv tmp trd tur tv vet vlog wiki zlg ",bs:" com edu gov net org ",bz:" du et om ov rg ",ca:" ab bc mb nb nf nl ns nt nu on pe qc sk yk ", +ck:" biz co edu gen gov info net org ",cn:" ac ah bj com cq edu fj gd gov gs gx gz ha hb he hi hl hn jl js jx ln mil net nm nx org qh sc sd sh sn sx tj tw xj xz yn zj ",co:" com edu gov mil net nom org ",cr:" ac c co ed fi go or sa ",cy:" ac biz com ekloges gov ltd name net org parliament press pro tm ","do":" art com edu gob gov mil net org sld web ",dz:" art asso com edu gov net org pol ",ec:" com edu fin gov info med mil net org pro ",eg:" com edu eun gov mil name net org sci ",er:" com edu gov ind mil net org rochest w ", +es:" com edu gob nom org ",et:" biz com edu gov info name net org ",fj:" ac biz com info mil name net org pro ",fk:" ac co gov net nom org ",fr:" asso com f gouv nom prd presse tm ",gg:" co net org ",gh:" com edu gov mil org ",gn:" ac com gov net org ",gr:" com edu gov mil net org ",gt:" com edu gob ind mil net org ",gu:" com edu gov net org ",hk:" com edu gov idv net org ",hu:" 2000 agrar bolt casino city co erotica erotika film forum games hotel info ingatlan jogasz konyvelo lakas media news org priv reklam sex shop sport suli szex tm tozsde utazas video ", +id:" ac co go mil net or sch web ",il:" ac co gov idf k12 muni net org ","in":" ac co edu ernet firm gen gov i ind mil net nic org res ",iq:" com edu gov i mil net org ",ir:" ac co dnssec gov i id net org sch ",it:" edu gov ",je:" co net org ",jo:" com edu gov mil name net org sch ",jp:" ac ad co ed go gr lg ne or ",ke:" ac co go info me mobi ne or sc ",kh:" com edu gov mil net org per ",ki:" biz com de edu gov info mob net org tel ",km:" asso com coop edu gouv k medecin mil nom notaires pharmaciens presse tm veterinaire ", +kn:" edu gov net org ",kr:" ac busan chungbuk chungnam co daegu daejeon es gangwon go gwangju gyeongbuk gyeonggi gyeongnam hs incheon jeju jeonbuk jeonnam k kg mil ms ne or pe re sc seoul ulsan ",kw:" com edu gov net org ",ky:" com edu gov net org ",kz:" com edu gov mil net org ",lb:" com edu gov net org ",lk:" assn com edu gov grp hotel int ltd net ngo org sch soc web ",lr:" com edu gov net org ",lv:" asn com conf edu gov id mil net org ",ly:" com edu gov id med net org plc sch ",ma:" ac co gov m net org press ", +mc:" asso tm ",me:" ac co edu gov its net org priv ",mg:" com edu gov mil nom org prd tm ",mk:" com edu gov inf name net org pro ",ml:" com edu gov net org presse ",mn:" edu gov org ",mo:" com edu gov net org ",mt:" com edu gov net org ",mv:" aero biz com coop edu gov info int mil museum name net org pro ",mw:" ac co com coop edu gov int museum net org ",mx:" com edu gob net org ",my:" com edu gov mil name net org sch ",nf:" arts com firm info net other per rec store web ",ng:" biz com edu gov mil mobi name net org sch ", +ni:" ac co com edu gob mil net nom org ",np:" com edu gov mil net org ",nr:" biz com edu gov info net org ",om:" ac biz co com edu gov med mil museum net org pro sch ",pe:" com edu gob mil net nom org sld ",ph:" com edu gov i mil net ngo org ",pk:" biz com edu fam gob gok gon gop gos gov net org web ",pl:" art bialystok biz com edu gda gdansk gorzow gov info katowice krakow lodz lublin mil net ngo olsztyn org poznan pwr radom slupsk szczecin torun warszawa waw wroc wroclaw zgora ",pr:" ac biz com edu est gov info isla name net org pro prof ", +ps:" com edu gov net org plo sec ",pw:" belau co ed go ne or ",ro:" arts com firm info nom nt org rec store tm www ",rs:" ac co edu gov in org ",sb:" com edu gov net org ",sc:" com edu gov net org ",sh:" co com edu gov net nom org ",sl:" com edu gov net org ",st:" co com consulado edu embaixada gov mil net org principe saotome store ",sv:" com edu gob org red ",sz:" ac co org ",tr:" av bbs bel biz com dr edu gen gov info k12 name net org pol tel tsk tv web ",tt:" aero biz cat co com coop edu gov info int jobs mil mobi museum name net org pro tel travel ", +tw:" club com ebiz edu game gov idv mil net org ",mu:" ac co com gov net or org ",mz:" ac co edu gov org ",na:" co com ",nz:" ac co cri geek gen govt health iwi maori mil net org parliament school ",pa:" abo ac com edu gob ing med net nom org sld ",pt:" com edu gov int net nome org publ ",py:" com edu gov mil net org ",qa:" com edu gov mil net org ",re:" asso com nom ",ru:" ac adygeya altai amur arkhangelsk astrakhan bashkiria belgorod bir bryansk buryatia cbg chel chelyabinsk chita chukotka chuvashia com dagestan e-burg edu gov grozny int irkutsk ivanovo izhevsk jar joshkar-ola kalmykia kaluga kamchatka karelia kazan kchr kemerovo khabarovsk khakassia khv kirov koenig komi kostroma kranoyarsk kuban kurgan kursk lipetsk magadan mari mari-el marine mil mordovia mosreg msk murmansk nalchik net nnov nov novosibirsk nsk omsk orenburg org oryol penza perm pp pskov ptz rnd ryazan sakhalin samara saratov simbirsk smolensk spb stavropol stv surgut tambov tatarstan tom tomsk tsaritsyn tsk tula tuva tver tyumen udm udmurtia ulan-ude vladikavkaz vladimir vladivostok volgograd vologda voronezh vrn vyatka yakutia yamal yekaterinburg yuzhno-sakhalinsk ", +rw:" ac co com edu gouv gov int mil net ",sa:" com edu gov med net org pub sch ",sd:" com edu gov info med net org tv ",se:" a ac b bd c d e f g h i k l m n o org p parti pp press r s t tm u w x y z ",sg:" com edu gov idn net org per ",sn:" art com edu gouv org perso univ ",sy:" com edu gov mil net news org ",th:" ac co go in mi net or ",tj:" ac biz co com edu go gov info int mil name net nic org test web ",tn:" agrinet com defense edunet ens fin gov ind info intl mincom nat net org perso rnrt rns rnu tourism ", +tz:" ac co go ne or ",ua:" biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ",ug:" ac co go ne or org sc ",uk:" ac bl british-library co cym gov govt icnet jet lea ltd me mil mod national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ", +us:" dni fed isa kids nsn ",uy:" com edu gub mil net org ",ve:" co com edu gob info mil net org web ",vi:" co com k12 net org ",vn:" ac biz com edu gov health info int name net org pro ",ye:" co com gov ltd me net org plc ",yu:" ac co edu gov org ",za:" ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ",zm:" ac co com edu gov net org sch ",com:"ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ",net:"gb jp se uk ", +org:"ae",de:"com "},has:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return!1;var q=m.lastIndexOf(".",d-1);if(0>=q||q>=d-1)return!1;var E=l.list[m.slice(d+1)];return E?0<=E.indexOf(" "+m.slice(q+1,d)+" "):!1},is:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1||0<=m.lastIndexOf(".",d-1))return!1;var q=l.list[m.slice(d+1)];return q?0<=q.indexOf(" "+m.slice(0,d)+" "):!1},get:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return null;var q=m.lastIndexOf(".",d-1); +if(0>=q||q>=d-1)return null;var E=l.list[m.slice(d+1)];return!E||0>E.indexOf(" "+m.slice(q+1,d)+" ")?null:m.slice(q+1)},noConflict:function(){r.SecondLevelDomains===this&&(r.SecondLevelDomains=w);return this}};return l}); +(function(r,w){"object"===typeof module&&module.exports?module.exports=w(require("./punycode"),require("./IPv6"),require("./SecondLevelDomains")):"function"===typeof define&&define.amd?define(["./punycode","./IPv6","./SecondLevelDomains"],w):r.URI=w(r.punycode,r.IPv6,r.SecondLevelDomains,r)})(this,function(r,w,l,m){function d(a,b){var c=1<=arguments.length,e=2<=arguments.length;if(!(this instanceof d))return c?e?new d(a,b):new d(a):new d;if(void 0===a){if(c)throw new TypeError("undefined is not a valid argument for URI"); +a="undefined"!==typeof location?location.href+"":""}if(null===a&&c)throw new TypeError("null is not a valid argument for URI");this.href(a);return void 0!==b?this.absoluteTo(b):this}function q(a){return a.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function E(a){return void 0===a?"Undefined":String(Object.prototype.toString.call(a)).slice(8,-1)}function z(a){return"Array"===E(a)}function k(a,b){var c={},e;if("RegExp"===E(b))c=null;else if(z(b)){var f=0;for(e=b.length;f]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u2018\u2019]))/ig;d.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u201e\u2018\u2019]+$/,parens:/(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g};d.defaultPorts={http:"80",https:"443",ftp:"21", +gopher:"70",ws:"80",wss:"443"};d.hostProtocols=["http","https"];d.invalid_hostname_characters=/[^a-zA-Z0-9\.\-:_]/;d.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"};d.getDomAttribute=function(a){if(a&&a.nodeName){var b=a.nodeName.toLowerCase();if("input"!==b||"image"===a.type)return d.domAttributes[b]}};d.encode=F;d.decode=decodeURIComponent;d.iso8859= +function(){d.encode=escape;d.decode=unescape};d.unicode=function(){d.encode=F;d.decode=decodeURIComponent};d.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/ig,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@", +"%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}};d.encodeQuery=function(a,b){var c=d.encode(a+"");void 0===b&&(b=d.escapeQuerySpace);return b?c.replace(/%20/g,"+"):c};d.decodeQuery= +function(a,b){a+="";void 0===b&&(b=d.escapeQuerySpace);try{return d.decode(b?a.replace(/\+/g,"%20"):a)}catch(c){return a}};var H={encode:"encode",decode:"decode"},G,n=function(a,b){return function(c){try{return d[b](c+"").replace(d.characters[a][b].expression,function(e){return d.characters[a][b].map[e]})}catch(e){return c}}};for(G in H)d[G+"PathSegment"]=n("pathname",H[G]),d[G+"UrnPathSegment"]=n("urnpath",H[G]);H=function(a,b,c){return function(e){var f=c?function(J){return d[b](d[c](J))}:d[b]; +e=(e+"").split(a);for(var h=0,A=e.length;he)return a.charAt(0)===b.charAt(0)&&"/"===a.charAt(0)?"/":"";if("/"!==a.charAt(e)||"/"!==b.charAt(e))e=a.substring(0,e).lastIndexOf("/");return a.substring(0,e+1)};d.withinString=function(a,b,c){c||(c={});var e=c.start||d.findUri.start,f=c.end||d.findUri.end,h=c.trim||d.findUri.trim,A=c.parens||d.findUri.parens,J=/[a-z0-9-]=["']?$/i; +for(e.lastIndex=0;;){var M=e.exec(a);if(!M)break;var P=M.index;if(c.ignoreHtml){var N=a.slice(Math.max(P-3,0),P);if(N&&J.test(N))continue}var O=P+a.slice(P).search(f);N=a.slice(P,O);for(O=-1;;){var Q=A.exec(N);if(!Q)break;O=Math.max(O,Q.index+Q[0].length)}N=-1b))throw new TypeError('Port "'+a+'" is not a valid port');}};d.noConflict=function(a){if(a)return a={URI:this.noConflict()},m.URITemplate&&"function"===typeof m.URITemplate.noConflict&&(a.URITemplate=m.URITemplate.noConflict()),m.IPv6&&"function"===typeof m.IPv6.noConflict&&(a.IPv6=m.IPv6.noConflict()),m.SecondLevelDomains&&"function"===typeof m.SecondLevelDomains.noConflict&&(a.SecondLevelDomains=m.SecondLevelDomains.noConflict()),a;m.URI===this&&(m.URI= +C);return this};g.build=function(a){if(!0===a)this._deferred_build=!0;else if(void 0===a||this._deferred_build)this._string=d.build(this._parts),this._deferred_build=!1;return this};g.clone=function(){return new d(this)};g.valueOf=g.toString=function(){return this.build(!1)._string};g.protocol=u("protocol");g.username=u("username");g.password=u("password");g.hostname=u("hostname");g.port=u("port");g.query=I("query","?");g.fragment=I("fragment","#");g.search=function(a,b){var c=this.query(a,b);return"string"=== +typeof c&&c.length?"?"+c:c};g.hash=function(a,b){var c=this.fragment(a,b);return"string"===typeof c&&c.length?"#"+c:c};g.pathname=function(a,b){if(void 0===a||!0===a){var c=this._parts.path||(this._parts.hostname?"/":"");return a?(this._parts.urn?d.decodeUrnPath:d.decodePath)(c):c}this._parts.path=this._parts.urn?a?d.recodeUrnPath(a):"":a?d.recodePath(a):"/";this.build(!b);return this};g.path=g.pathname;g.href=function(a,b){var c;if(void 0===a)return this.toString();this._string="";this._parts=d._parts(); +var e=a instanceof d,f="object"===typeof a&&(a.hostname||a.path||a.pathname);a.nodeName&&(f=d.getDomAttribute(a),a=a[f]||"",f=!1);!e&&f&&void 0!==a.pathname&&(a=a.toString());if("string"===typeof a||a instanceof String)this._parts=d.parse(String(a),this._parts);else if(e||f){e=e?a._parts:a;for(c in e)"query"!==c&&y.call(this._parts,c)&&(this._parts[c]=e[c]);e.query&&this.query(e.query,!1)}else throw new TypeError("invalid input");this.build(!b);return this};g.is=function(a){var b=!1,c=!1,e=!1,f=!1, +h=!1,A=!1,J=!1,M=!this._parts.urn;this._parts.hostname&&(M=!1,c=d.ip4_expression.test(this._parts.hostname),e=d.ip6_expression.test(this._parts.hostname),b=c||e,h=(f=!b)&&l&&l.has(this._parts.hostname),A=f&&d.idn_expression.test(this._parts.hostname),J=f&&d.punycode_expression.test(this._parts.hostname));switch(a.toLowerCase()){case "relative":return M;case "absolute":return!M;case "domain":case "name":return f;case "sld":return h;case "ip":return b;case "ip4":case "ipv4":case "inet4":return c;case "ip6":case "ipv6":case "inet6":return e; +case "idn":return A;case "url":return!this._parts.urn;case "urn":return!!this._parts.urn;case "punycode":return J}return null};var t=g.protocol,D=g.port,x=g.hostname;g.protocol=function(a,b){if(a&&(a=a.replace(/:(\/\/)?$/,""),!a.match(d.protocol_expression)))throw new TypeError('Protocol "'+a+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return t.call(this,a,b)};g.scheme=g.protocol;g.port=function(a,b){if(this._parts.urn)return void 0===a?"":this;void 0!==a&&(0===a&& +(a=null),a&&(a+="",":"===a.charAt(0)&&(a=a.substring(1)),d.ensureValidPort(a)));return D.call(this,a,b)};g.hostname=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0!==a){var c={preventInvalidHostname:this._parts.preventInvalidHostname};if("/"!==d.parseHost(a,c))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');a=c.hostname;this._parts.preventInvalidHostname&&d.ensureValidHostname(a,this._parts.protocol)}return x.call(this,a,b)};g.origin=function(a, +b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){var c=this.protocol();return this.authority()?(c?c+"://":"")+this.authority():""}c=d(a);this.protocol(c.protocol()).authority(c.authority()).build(!b);return this};g.host=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildHost(this._parts):"";if("/"!==d.parseHost(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);return this}; +g.authority=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildAuthority(this._parts):"";if("/"!==d.parseAuthority(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);return this};g.userinfo=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){var c=d.buildUserinfo(this._parts);return c?c.substring(0,c.length-1):c}"@"!==a[a.length-1]&&(a+="@");d.parseUserinfo(a, +this._parts);this.build(!b);return this};g.resource=function(a,b){if(void 0===a)return this.path()+this.search()+this.hash();var c=d.parse(a);this._parts.path=c.path;this._parts.query=c.query;this._parts.fragment=c.fragment;this.build(!b);return this};g.subdomain=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,c)||""}c=this._parts.hostname.length- +this.domain().length;c=this._parts.hostname.substring(0,c);c=new RegExp("^"+q(c));a&&"."!==a.charAt(a.length-1)&&(a+=".");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");a&&d.ensureValidHostname(a,this._parts.protocol);this._parts.hostname=this._parts.hostname.replace(c,a);this.build(!b);return this};g.domain=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c= +this._parts.hostname.match(/\./g);if(c&&2>c.length)return this._parts.hostname;c=this._parts.hostname.length-this.tld(b).length-1;c=this._parts.hostname.lastIndexOf(".",c-1)+1;return this._parts.hostname.substring(c)||""}if(!a)throw new TypeError("cannot set domain empty");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");d.ensureValidHostname(a,this._parts.protocol);!this._parts.hostname||this.is("IP")?this._parts.hostname=a:(c=new RegExp(q(this.domain())+"$"),this._parts.hostname= +this._parts.hostname.replace(c,a));this.build(!b);return this};g.tld=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c=this._parts.hostname.lastIndexOf(".");c=this._parts.hostname.substring(c+1);return!0!==b&&l&&l.list[c.toLowerCase()]?l.get(this._parts.hostname)||c:c}if(a)if(a.match(/[^a-zA-Z0-9-]/))if(l&&l.is(a))c=new RegExp(q(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(c, +a);else throw new TypeError('TLD "'+a+'" contains characters other than [A-Z0-9]');else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");c=new RegExp(q(this.tld())+"$");this._parts.hostname=this._parts.hostname.replace(c,a)}else throw new TypeError("cannot set TLD empty");this.build(!b);return this};g.directory=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a||!0===a){if(!this._parts.path&&!this._parts.hostname)return""; +if("/"===this._parts.path)return"/";var c=this._parts.path.length-this.filename().length-1;c=this._parts.path.substring(0,c)||(this._parts.hostname?"/":"");return a?d.decodePath(c):c}c=this._parts.path.length-this.filename().length;c=this._parts.path.substring(0,c);c=new RegExp("^"+q(c));this.is("relative")||(a||(a="/"),"/"!==a.charAt(0)&&(a="/"+a));a&&"/"!==a.charAt(a.length-1)&&(a+="/");a=d.recodePath(a);this._parts.path=this._parts.path.replace(c,a);this.build(!b);return this};g.filename=function(a, +b){if(this._parts.urn)return void 0===a?"":this;if("string"!==typeof a){if(!this._parts.path||"/"===this._parts.path)return"";var c=this._parts.path.lastIndexOf("/");c=this._parts.path.substring(c+1);return a?d.decodePathSegment(c):c}c=!1;"/"===a.charAt(0)&&(a=a.substring(1));a.match(/\.?\//)&&(c=!0);var e=new RegExp(q(this.filename())+"$");a=d.recodePath(a);this._parts.path=this._parts.path.replace(e,a);c?this.normalizePath(b):this.build(!b);return this};g.suffix=function(a,b){if(this._parts.urn)return void 0=== +a?"":this;if(void 0===a||!0===a){if(!this._parts.path||"/"===this._parts.path)return"";var c=this.filename(),e=c.lastIndexOf(".");if(-1===e)return"";c=c.substring(e+1);c=/^[a-z0-9%]+$/i.test(c)?c:"";return a?d.decodePathSegment(c):c}"."===a.charAt(0)&&(a=a.substring(1));if(c=this.suffix())e=a?new RegExp(q(c)+"$"):new RegExp(q("."+c)+"$");else{if(!a)return this;this._parts.path+="."+d.recodePath(a)}e&&(a=d.recodePath(a),this._parts.path=this._parts.path.replace(e,a));this.build(!b);return this};g.segment= +function(a,b,c){var e=this._parts.urn?":":"/",f=this.path(),h="/"===f.substring(0,1);f=f.split(e);void 0!==a&&"number"!==typeof a&&(c=b,b=a,a=void 0);if(void 0!==a&&"number"!==typeof a)throw Error('Bad segment "'+a+'", must be 0-based integer');h&&f.shift();0>a&&(a=Math.max(f.length+a,0));if(void 0===b)return void 0===a?f:f[a];if(null===a||void 0===f[a])if(z(b)){f=[];a=0;for(var A=b.length;a{}"`^| \\]/;l.expand=function(k,p,B){var v=z[k.operator],K=v.named?"Named":"Unnamed";k=k.variables;var F=[],u,I;for(I=0;u=k[I];I++){var C=p.get(u.name);if(0===C.type&&B&&B.strict)throw Error('Missing expansion value for variable "'+ +u.name+'"');if(C.val.length){if(1