Jump to content

need help with a small problem in my algorithm


Guest
 Share

Recommended Posts

Hello,

i worte a algorithm that reed this log file for example:

Dup 2.30 by Donald Graft/Klaus Post, Copyright 2003-2007

Dup: frm 0: Using frm 20

Dup: frm 1: Using frm 20

Dup: frm 2: Using frm 20

Dup: frm 3: Using frm 20

Dup: frm 4: Using frm 20

Dup: frm 5: Using frm 20

Dup: frm 6: Using frm 20

Dup: frm 7: Using frm 20

Dup: frm 8: Using frm 20

Dup: frm 9: Using frm 20

Dup: frm 10: Using frm 20

Dup: frm 11: Using frm 20

Dup: frm 12: Using frm 20

Dup: frm 13: Using frm 20

Dup: frm 14: Using frm 20

Dup: frm 15: Using frm 20

Dup: frm 16: Using frm 20

Dup: frm 17: Using frm 20

Dup: frm 18: Using frm 20

Dup: frm 19: Using frm 20

Dup: frm 20: Using frm 20

Dup: frm 21: Using frm 41

Dup: frm 22: Using frm 41

Dup: frm 23: Using frm 41

Dup: frm 24: Using frm 41

Dup: frm 25: Using frm 41

Dup: frm 26: Using frm 41

Dup: frm 27: Using frm 41

Dup: frm 28: Using frm 41

Dup: frm 29: Using frm 41

Dup: frm 30: Using frm 41

Dup: frm 31: Using frm 41

Dup: frm 32: Using frm 41

Dup: frm 33: Using frm 41

Dup: frm 34: Using frm 41

Dup: frm 35: Using frm 41

Dup: frm 36: Using frm 41

Dup: frm 37: Using frm 41

Dup: frm 38: Using frm 41

Dup: frm 39: Using frm 41

Dup: frm 40: Using frm 41

Dup: frm 41: Using frm 41

Dup: frm 42: Using frm 62

Dup: frm 43: Using frm 62

Dup: frm 44: Using frm 62

Dup: frm 45: Using frm 62

Dup: frm 46: Using frm 62

Dup: frm 47: Using frm 62

Dup: frm 48: Using frm 62

Dup: frm 49: Using frm 62

and this is my code:

#Include <File.au3>
#include <Array.au3>

Local $aFile0 , $DupData[1] , $NDupData = 0 , $Duplogfile = "Dup cap2.txt"
_FileReadToArray($Duplogfile,$aFile0)
For $i = 3 to $aFile0[0]
;ConsoleWrite($aFile[$i] & @crlf)
$var = StringSplit($aFile0[$i]," frm ",1)
    If $var[0] = 3 Then
        $frame = $var[3]
        ;MsgBox(0,"",$var[2])
        $n = 1
            While 1
                If  $i+$n < $aFile0[0] Then
                    $var = StringSplit($aFile0[$i+$n]," frm ",1)
                    If $var[3] = $frame Then
                        $var2 = StringTrimLeft($aFile0[$i+$n],StringLen("Dup: frm "))
                        $var2 = StringSplit($var2,":",1)
                        ;MsgBox(0,"",$var2[1])
                        _ArrayAdd($DupData,$var2[1]&" , "&$frame)
                        $NDupData = $NDupData+1
                        $n = $n+1
                    Else
                        $i = $i+$n
                        ExitLoop
                    EndIf
                Else
                    ExitLoop
                EndIf
            WEnd
    EndIf
Next        
_ArrayDisplay($DupData, "$DupData")

the problem is that it is missing some numbers:

Posted Image

EDIT:

The goal of the algorithm is to write only the red areas:

Dup: frm 162: Using frm 162

Dup: frm 163: Using frm 163

Dup: frm 164: Using frm 164

Dup: frm 165: Using frm 165

Dup: frm 166: Using frm 166

Dup: frm 167: Using frm 167

Dup: frm 168: Using frm 168

Dup: frm 169: Using frm 169

Dup: frm 170: Using frm 170

Dup: frm 177: Using frm 177

Dup: frm 178: Using frm 178

Dup: frm 179: Using frm 179

Dup: frm 180: Using frm 180

Dup: frm 181: Using frm 181

Dup: frm 182: Using frm 182

Dup: frm 183: Using frm 183

Dup: frm 184: Using frm 184

Dup: frm 185: Using frm 185

Dup: frm 186: Using frm 196

Dup: frm 187: Using frm 196

Dup: frm 188: Using frm 196

Dup: frm 189: Using frm 196

Dup: frm 190: Using frm 196

Dup: frm 191: Using frm 196

Dup: frm 192: Using frm 196

Dup: frm 193: Using frm 196

Dup: frm 194: Using frm 196

Dup: frm 195: Using frm 196

Dup: frm 196: Using frm 196

Dup: frm 197: Using frm 197

Dup: frm 198: Using frm 198

Dup: frm 199: Using frm 199

Dup: frm 200: Using frm 200

Dup: frm 201: Using frm 201

Dup: frm 202: Using frm 202

Dup: frm 203: Using frm 221

Dup: frm 204: Using frm 221

Dup: frm 205: Using frm 221

Dup: frm 206: Using frm 221

Dup: frm 207: Using frm 221

Dup: frm 208: Using frm 221

Dup: frm 209: Using frm 221

Dup: frm 210: Using frm 221

Dup: frm 211: Using frm 221

Dup: frm 212: Using frm 221

Dup: frm 213: Using frm 221

Dup: frm 214: Using frm 221

Dup: frm 215: Using frm 221

Dup: frm 216: Using frm 221

Dup: frm 217: Using frm 221

Dup: frm 218: Using frm 221

Dup: frm 219: Using frm 221

Dup: frm 220: Using frm 221

Dup: frm 221: Using frm 221

Dup: frm 222: Using frm 229

Dup: frm 223: Using frm 229

Dup: frm 224: Using frm 229

Dup: frm 225: Using frm 229

Dup: frm 226: Using frm 229

Dup: frm 227: Using frm 229

Dup: frm 228: Using frm 229

Dup: frm 229: Using frm 229

Dup: frm 230: Using frm 230

Dup: frm 231: Using frm 231

Dup: frm 232: Using frm 233

Dup: frm 233: Using frm 233

Dup: frm 234: Using frm 234

Dup: frm 235: Using frm 235

Dup: frm 236: Using frm 238

Dup: frm 237: Using frm 238

Dup: frm 238: Using frm 238

Dup: frm 239: Using frm 239

Dup: frm 240: Using frm 240

Dup: frm 241: Using frm 241

Dup: frm 242: Using frm 242

Dup: frm 243: Using frm 243

What I did wrong?

Edited by Guest
Link to comment
Share on other sites

Hi,

Here you go :

#include <File.au3>
#include <String.au3>
#include <Array.au3>

Local $aRead = 0
_FileReadToArray("s.txt", $aRead)

Local $aOutput[$aRead[0] - 2][2]

For $i = 3 To $aRead[0]
    $atmp = _StringBetween($aRead[$i], "Dup: frm ", ":")
    $aOutput[$i - 3][0] = $atmp[0]

    $aOutput[$i - 3][1] = StringTrimLeft($aRead[$i], StringInStr($aRead[$i], "Using frm ", 2) + 9)
Next

_ArrayDisplay($aOutput)

Br, FireFox.

Link to comment
Share on other sites

Hi,

Here you go :

#include <File.au3>
#include <String.au3>
#include <Array.au3>

Local $aRead = 0
_FileReadToArray("s.txt", $aRead)

Local $aOutput[$aRead[0] - 2][2]

For $i = 3 To $aRead[0]
    $atmp = _StringBetween($aRead[$i], "Dup: frm ", ":")
    $aOutput[$i - 3][0] = $atmp[0]

    $aOutput[$i - 3][1] = StringTrimLeft($aRead[$i], StringInStr($aRead[$i], "Using frm ", 2) + 9)
Next

_ArrayDisplay($aOutput)

Br, FireFox.

Thank you.

Did you read the example I added?

Take a closer look

It's a bit tricky

Link to comment
Share on other sites

Well, I don't want to have a headache as your code is too much complicated.

First advice: Never use _ArrayAdd/Insert in a loop as the array is resized, meaning that the old has to be copied in memory with the new size and the old one deleted.

I will take a look at your script and tell you what's wrong. However, I suggest you to keep mine :P

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

 

On 10.4.2013 at 1:44 PM, 'FireFox said:

Well, I don't want to have a headache as your code is too much complicated.

 

First advice: Never use _ArrayAdd/Insert in a loop as the array is resized, meaning that the old has to be copied in memory with the new size and the old one deleted.

 

I will take a look at your script and tell you what's wrong. However, I suggest you to keep mine :P

 

Br, FireFox.

 

Ok thank you!

This code goes through the 39610 lines ..

 

Originally, it should take a long time. But I added a few things that minimize the process to 2 seconds..

 

I wrote this some time ago .. I do not remember exactly what else shortens the process.

 

This code is complicated. And like you, I also try not to get a headache.

That's why I use the forum :)

 

EDIT:

 

your script doing this in much more time then my script

 

if you want to test it on big file so download this:

Dup cap2.txt

Edited by Guest
Link to comment
Share on other sites

Update:

Okay. I've found that if I increase the variable $n So the algorithm misses more ..

For example, if n = 2, the algorithm will miss 2.

So what is expected is that if $ n is 0, the algorithm will not miss anything.

As theory, it should work.

In fact it really works ..

But here begins the mystery -

_ArrayAdd Command in line 20 the script, does not allow the loop to end.

I do not know why ..

But I loop never ends ..

Only if I disable the line 20 then the process ends ..

It does not help me because I have to use this information ..

If I do not write the information so I did not do anything ..

Could it be a bug in _ArrayAdd() ?

Edited by Guest
Link to comment
Share on other sites

Your script may be faster because it skipped some lines as you noticed.

Can you explain to me what is the logic to get the red areas?

Now I begin to remember the logic ..

When I wrote the script, I knew that $n must be greater than 1.

The logic is:

1) Count how many times repeat the same number on the right. $n represents the count.

2) If the number appears again, then $n must be greater than 1. That the same number is counted several times.

If this happens then it enters to this new loop:

While 1
    If  $i+$n < $aFile0[0] Then
        $var = StringSplit($aFile0[$i+$n]," frm ",1)
        If $var[3] = $frame Then
            $var2 = StringTrimLeft($aFile0[$i+$n],StringLen("Dup: frm "))
            $var2 = StringSplit($var2,":",1)
            ;MsgBox(0,"",$var2[1])
            _ArrayAdd($DupData,$var2[1]&" , "&$frame)
            $NDupData = $NDupData+1
            $n = $n+1
        Else
            $i = $i+$n
            ExitLoop
        EndIf
    Else
        ExitLoop
    EndIf
WEnd
Edited by Guest
Link to comment
Share on other sites

Does this produce the result you want?

Local $Duplogfile = "Dup cap2.txt"
Local $sLog = FileRead($Duplogfile)
Local $DupData = StringRegExpReplace($sLog, "(?m)(^Dup: frm \d+: Using frm (\d+)\R)((?:Dup: frm \d+: Using frm \2\R)*)", "$3")
ConsoleWrite($DupData)

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Look at regular expressions and the usage of syntax. For example d+ means 1 or more integers.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

OK, let me break down this regular expression replacement:

First we read the whole file into a single variable, then we replace what's matching the pattern with the capture number 3 (see below).

The idea is to look at the file as a series of blocks containing:

a first line (this is capture number 1) with "Using frm " and a number which we capture under number 2 followed by a sub-block of zero or more lines having the same "Using frm " value as capture number 2. What we're interessed in is this sub-block which we capture as number 3. Then comes the replacement action: we replace the whole block with the (possibly empty) sub-block containing exactly what we want to keep in the result.

(?m)    causes the Regex engine to treat the whole file Assign(one single stream of characters, (i.e. not line by line)
(Dup: frm \d+: Using frm (\d+)\R)    here we match the first line of every block in the outer parenthesis (capture #1)
                                    (\d+) means one or more digit and this is capture #2
((?:Dup: frm \d+: Using frm \2\R)*)    here we match a sub-block (possibly empty) of zero or more lines "Using frm " and value = capture #2
                                    this is capture #3. Note that the inner (?: ...) group does NOT capture anything
                                    
Finally we replace the whole match above with what's left in capture #3, referred to as "$3" in the replacement string

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

ok thanks..

I prefer to do everything myself and in my way

And I managed to do it!

#Include <File.au3>
#include <Array.au3>

Local $aFile0 , $DupData[1] , $NDupData = 0 , $Duplogfile = "Dup cap2.txt"
_FileReadToArray($Duplogfile,$aFile0)
For $a = 3 to $aFile0[0]
;ConsoleWrite($aFile[$i] & @crlf)
$var = StringSplit($aFile0[$a]," frm ",1)
    If $var[0] = 3 Then
        $frame1 = $var[3]
        $first = True
        $n = 1
        While 1
            $var = StringSplit($aFile0[$a+$n]," frm ",1)
            If $var[0] = 3 Then
                ;ToolTip("test"&" , "&$i)
                $frame2 = $var[3]
                ;ToolTip($frame2)
                If $frame1 = $frame2 Then
                    For $b = $a+$n To $aFile0[0]
                        ;MsgBox(0,"",$b)
                        $var2 = StringSplit($aFile0[$b]," frm ",1)
                        $n = $n+1
                        $badframe = StringSplit($var2[2],":",1)
                        $badframe = $badframe[1]
                        If $badframe <> $frame1 Or $badframe = $frame1 Then
                            _ArrayAdd($DupData,$badframe&" , "&$frame1)
                            ;$n = $n+1
                            If $badframe = $frame1 Then
                                $a = $b
                                ExitLoop
                            EndIf
                        EndIf
                    Next
                Else
                    ;$a = $a+$n
                    ExitLoop
                EndIf
            Else
                ExitLoop
            EndIf
        WEnd
    EndIf
Next        
_ArrayDisplay($DupData, "$DupData")
Link to comment
Share on other sites

I could use jchd's solution.

but I prefer to write the majority part alone

I believe that jchd's solution is also complicated. but the complicated part is hidden behind the StringRegExpReplace() function..

i wanted to get it in Array and not in one variable

Edited by Guest
Link to comment
Share on other sites

All laudible, you were concerned with speed earlier and thus my comment...

Oh .. It takes about the same time.

In both cases it takes about 2.5 seconds

Link to comment
Share on other sites

Should you need an arry instead, replace the ConsoleWrite() by

$DupData = StringSplit($DupData, @CRLF, 3)
_ArrayDisplay($DupData)

That doesn't surprise me that this regexp is not terribly fast. This has to do with the nature of the problem and also with how PCRE is implemented inside AutoIt. Not using ConsoleWrite will obviously speed up things but you knew that, didn't you?

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

but I prefer to write the majority part alone

Great, but it's good to also listen and take advice as it might be worth something later on.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...