问:
start() for BlockOperation on the main thread
Why is calling start() for BlockOperation with more then 1 block on a main thread not calling its block on the main thread?
My first test is always passed but second not every time - some times blocks executes not on the main thread

```<code>func test_callStartOnMainThread_executeOneBlockOnMainThread() {
    let blockOper = BlockOperation {
        XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
    }
    blockOper.start()
}
func test_callStartOnMainThread_executeTwoBlockOnMainThread() {
    let blockOper = BlockOperation {
        XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
    }
    blockOper.addExecutionBlock {
        XCTAssertTrue(Thread.isMainThread, "Expect second block was executed on Main Thread")
    }
    blockOper.start()
}
</code>```

Even next code is failed

```<code>func test_callStartOnMainThread_executeTwoBlockOnMainThread() {
    let asyncExpectation = expectation(description: "Async block executed")
    asyncExpectation.expectedFulfillmentCount = 2
    let blockOper = BlockOperation {
        XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
        asyncExpectation.fulfill()
    }
    blockOper.addExecutionBlock {
        XCTAssertTrue(Thread.isMainThread, "Expect second block was executed on Main Thread")
        asyncExpectation.fulfill()
    }
    OperationQueue.main.addOperation(blockOper)
    wait(for: [asyncExpectation], timeout: 2.0)
}
</code>```

答:
As Andreas pointed out, the documentation warns us:

Blocks added to a block operation are dispatched with default priority to an appropriate work queue. The blocks themselves should not make any assumptions about the configuration of their execution environment.

The thread on which we start the operation, as well as the  maxConcurrentOperationCount behavior of the queue, is managed at the operation level, not at the individual execution blocks within an operation. Adding a block to an existing operation is not the same as adding a new operation to the queue. The operation queue governs the relationship between operations, not between the blocks within an operation.

The problem can be laid bare by making these blocks do something that takes a little time. Consider a task that waits one second (you would generally never sleep, but we're doing this simply to simulate a slow task and to manifest the behavior in question). I've also added the necessary “points of interest” code so we can watch this in Instruments, which makes it easier to visualize what’s going on:

```<code>import os.log
let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)

func someTask(_ message: String) {
    let id = OSSignpostID(log: pointsOfInterest)
    os_signpost(.begin, log: pointsOfInterest, name: "Block", signpostID: id, "Starting %{public}@", message)
    Thread.sleep(forTimeInterval: 1)
    os_signpost(.end, log: pointsOfInterest, name: "Block", signpostID: id, "Finishing %{public}@", message)
}
</code>```

Then use addExecutionBlock:

```<code>let queue = OperationQueue()          // you get same behavior if you replace these two lines with `let queue = OperationQueue.main`
queue.maxConcurrentOperationCount = 1

let operation = BlockOperation {
    self.someTask("main block")
}
operation.addExecutionBlock {
    self.someTask("add block 1")
}
operation.addExecutionBlock {
    self.someTask("add block 2")
}
queue.addOperation(operation)
</code>```

Now, I'm adding this to a serial operation queue (because you’d never add a blocking operation to the main queue ... we need to keep that queue free and responsive), but you see the same behavior if you manually start this on the OperationQueue.main. So, bottom line, while start will run the operation “immediately in the current thread”, any blocks you add with addExecutionBlock will just run, in parallel, on “an appropriate work queue”, not necessary the current thread.

If we watch this in Instruments, we can see that not only does addExecutionBlock not necessarily honor the thread on which the operation was started, but it doesn’t honor the serial nature of the queue, either, with the blocks running in parallel:

Obviously, if you add these blocks as individual operations, then everything is fine:

```<code>for i in 1 ... 3 {
    let operation = BlockOperation {
        self.someTask("main block\(i)")
    }
    queue.addOperation(operation)
}
</code>```

Yielding:

Body:
Why is calling start() for BlockOperation with more then 1 block on a main thread not calling its block on the main thread?
My first test is always passed but second not every time - some times blocks executes not on the main thread

func test_callStartOnMainThread_executeOneBlockOnMainThread() {
    let blockOper = BlockOperation {
        XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
    }
    blockOper.start()
}
func test_callStartOnMainThread_executeTwoBlockOnMainThread() {
    let blockOper = BlockOperation {
        XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
    }
    blockOper.addExecutionBlock {
        XCTAssertTrue(Thread.isMainThread, "Expect second block was executed on Main Thread")
    }
    blockOper.start()
}

Even next code is failed

func test_callStartOnMainThread_executeTwoBlockOnMainThread() {
    let asyncExpectation = expectation(description: "Async block executed")
    asyncExpectation.expectedFulfillmentCount = 2
    let blockOper = BlockOperation {
        XCTAssertTrue(Thread.isMainThread, "Expect first block was executed on Main Thread")
        asyncExpectation.fulfill()
    }
    blockOper.addExecutionBlock {
        XCTAssertTrue(Thread.isMainThread, "Expect second block was executed on Main Thread")
        asyncExpectation.fulfill()
    }
    OperationQueue.main.addOperation(blockOper)
    wait(for: [asyncExpectation], timeout: 2.0)
}

Body:
As Andreas pointed out, the documentation warns us:

Blocks added to a block operation are dispatched with default priority to an appropriate work queue. The blocks themselves should not make any assumptions about the configuration of their execution environment.

The thread on which we start the operation, as well as the  maxConcurrentOperationCount behavior of the queue, is managed at the operation level, not at the individual execution blocks within an operation. Adding a block to an existing operation is not the same as adding a new operation to the queue. The operation queue governs the relationship between operations, not between the blocks within an operation.

The problem can be laid bare by making these blocks do something that takes a little time. Consider a task that waits one second (you would generally never sleep, but we're doing this simply to simulate a slow task and to manifest the behavior in question). I've also added the necessary “points of interest” code so we can watch this in Instruments, which makes it easier to visualize what’s going on:

import os.log
let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)

func someTask(_ message: String) {
    let id = OSSignpostID(log: pointsOfInterest)
    os_signpost(.begin, log: pointsOfInterest, name: "Block", signpostID: id, "Starting %{public}@", message)
    Thread.sleep(forTimeInterval: 1)
    os_signpost(.end, log: pointsOfInterest, name: "Block", signpostID: id, "Finishing %{public}@", message)
}

Then use addExecutionBlock:

let queue = OperationQueue()          // you get same behavior if you replace these two lines with `let queue = OperationQueue.main`
queue.maxConcurrentOperationCount = 1

let operation = BlockOperation {
    self.someTask("main block")
}
operation.addExecutionBlock {
    self.someTask("add block 1")
}
operation.addExecutionBlock {
    self.someTask("add block 2")
}
queue.addOperation(operation)

Now, I'm adding this to a serial operation queue (because you’d never add a blocking operation to the main queue ... we need to keep that queue free and responsive), but you see the same behavior if you manually start this on the OperationQueue.main. So, bottom line, while start will run the operation “immediately in the current thread”, any blocks you add with addExecutionBlock will just run, in parallel, on “an appropriate work queue”, not necessary the current thread.

If we watch this in Instruments, we can see that not only does addExecutionBlock not necessarily honor the thread on which the operation was started, but it doesn’t honor the serial nature of the queue, either, with the blocks running in parallel:

Obviously, if you add these blocks as individual operations, then everything is fine:

for i in 1 ... 3 {
    let operation = BlockOperation {
        self.someTask("main block\(i)")
    }
    queue.addOperation(operation)
}

Yielding:


来源: stackexchange

问:
data passing in navigation based application
i am working on a navigation based application
in the rootviewcontroller i hav a few UITextFields. There is a button on rootviewController, on clicking that button i am changing the view using pushviewcontroller. I want to use values entered in these UItextFields in mapview ie my 2nd view.

PLZ suggest me something.

答:
Use an NSDictionary object to store the values from the first controller. Say you are using two text fields – textField1 and textField2.

```<code>- (void)loadSecondController {
    NSDictionary *values = [NSDictionary dictionaryWithObjectsAndKeys:textField1.text, @"textField1", textField2.text, @"textField2", nil];

    // Assuming you are using IB files
    SecondViewController *controller = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
    controller.values = values; // Declare a NSDictionary property 'values' in SecondViewController
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];
}
</code>```

Now in SecondViewController, you can access them as

```<code>...
textField1Value = [values objectForKey:@"textField1"];
textField2Value = [values objectForKey:@"textField2"];
...
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Use an NSDictionary object to store the values from the first controller. Say you are using two text fields – textField1 and textField2.

- (void)loadSecondController {
    NSDictionary *values = [NSDictionary dictionaryWithObjectsAndKeys:textField1.text, @"textField1", textField2.text, @"textField2", nil];

    // Assuming you are using IB files
    SecondViewController *controller = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
    controller.values = values; // Declare a NSDictionary property 'values' in SecondViewController
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];
}

Now in SecondViewController, you can access them as

...
textField1Value = [values objectForKey:@"textField1"];
textField2Value = [values objectForKey:@"textField2"];
...


问:
How do I jump to a closing bracket in Visual Studio Code?
In VSCode when I type a bracket, e.g '(', it automatically creates the ending bracket: ')'.
Are there any shortcuts to jump to the closing bracket or parenthesis, without pressing the 'End' key?

I found a way to do in Sublime Text 2 that did exactly that, using a Regex in the User's Key Bindings, but couldn't find a way to do it in VSCode.

答: On French keyboard the default binding is : Ctrl+Shift+*

ContentLicense: CC BY-SA 4.0


问:
Does heapq.heappush() compare on int AND string without been specified for?
I was checking out this solution to a question on leetcode.com

```<code>def topKFrequent(self, words, k):
        count = collections.Counter(words)
        heap = [(-freq, word) for word, freq in count.items()]
        heapq.heapify(heap)
        return [heapq.heappop(heap)[1] for _ in xrange(k)]
</code>```

and when I provide it an array of strings like ["aa", "aaa", "a"] and 1  it correctly returns ["a"]. My question is did the heap also lexographically sort the tuples internally? Because according to me if there was no sorting, it would have simply returned ["aa"] (the order in which the heap was constructed since counts of all three are the same). Or have I misunderstood heapq?

答:
heapq just compares values from the queue using using the "less than" operator [1] regardless of the type of the value. It is the type of the value that defines what the comparison will return. So, what makes the difference here is the tuple itself. As from the documentation:

The comparison [of sequence objects] uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted.

Checking some examples:

```<code>>>> (0, 'a') < (1, 'aa')
True
>>> (1, 'a') < (1, 'aa')
True
>>> (1, 'aa') < (1, 'a')
False
>>> (2, 'a') < (1, 'aa')
False
</code>```

So you are right, the values are ordered lexicographically and the second value of the tuple is relevant. However, heapq does not have to do anything here to get this result, the mere tuple comparison does that.

[1]  One can check it in the code. Here is one of the lines where the comparison is made by heapq (in C):

```<code>cmp = PyObject_RichCompareBool(newitem, parent, Py_LT);
</code>```

This PyObject_RichCompareBool() is, according to the documentation:

the equivalent of the Python expression o1 op o2, where op is the operator corresponding to opid.

Body:
I was checking out this solution to a question on leetcode.com

def topKFrequent(self, words, k):
        count = collections.Counter(words)
        heap = [(-freq, word) for word, freq in count.items()]
        heapq.heapify(heap)
        return [heapq.heappop(heap)[1] for _ in xrange(k)]

and when I provide it an array of strings like ["aa", "aaa", "a"] and 1  it correctly returns ["a"]. My question is did the heap also lexographically sort the tuples internally? Because according to me if there was no sorting, it would have simply returned ["aa"] (the order in which the heap was constructed since counts of all three are the same). Or have I misunderstood heapq?

Body:
heapq just compares values from the queue using using the "less than" operator [1] regardless of the type of the value. It is the type of the value that defines what the comparison will return. So, what makes the difference here is the tuple itself. As from the documentation:

The comparison [of sequence objects] uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted.

Checking some examples:

>>> (0, 'a') < (1, 'aa')
True
>>> (1, 'a') < (1, 'aa')
True
>>> (1, 'aa') < (1, 'a')
False
>>> (2, 'a') < (1, 'aa')
False

So you are right, the values are ordered lexicographically and the second value of the tuple is relevant. However, heapq does not have to do anything here to get this result, the mere tuple comparison does that.

[1]  One can check it in the code. Here is one of the lines where the comparison is made by heapq (in C):

cmp = PyObject_RichCompareBool(newitem, parent, Py_LT);

This PyObject_RichCompareBool() is, according to the documentation:

the equivalent of the Python expression o1 op o2, where op is the operator corresponding to opid.


问:
gcloud app enigne. where to create virtualenv? external directory to my project?
I'm starting to use gcloud and appengine and I don't know which is the best way to manage virtualenvs.

On the one hand, https://cloud.google.com/appengine/docs/standard/python3/quickstart

Create an isolated Python environment in a directory external to your project and activate it

But on the other hand, https://cloud.google.com/python/setup

```<code>cd your-project
python3 -m venv venv
</code>```

So, what should I do? I understand that the logic of creating the virtualenv outside the directory is due to not deploying the virtualenv when deploying the gcloud app, but there is no way to exclude it? If I'm working with vs code, I think that the virtualenv should be in the same folder where is the project.

Thanks for the help, my first question in stackoverflow!

答:
I recommend you keep the venv distinct from the project's sources (i.e. anything you'd like manage through source control).

I generally favor:

mkdir -p ${PROJECT}/python ${PROJECT}/venv
tree -L 1 ${PROJECT}
${PROJECT}
├── python
└── venv
```

This keeps the project together but permits me to whack ${PROJECT}/venv as I wish and it does not taint the code that gets deployed to e.g. App Engine.

I didn't see much of an inconsistency in the Google-published guidance.

You want to ensure that the venv directory is not deployed to App Engine.

Body:
I'm starting to use gcloud and appengine and I don't know which is the best way to manage virtualenvs.

On the one hand, https://cloud.google.com/appengine/docs/standard/python3/quickstart

Create an isolated Python environment in a directory external to your project and activate it

But on the other hand, https://cloud.google.com/python/setup

cd your-project
python3 -m venv venv

So, what should I do? I understand that the logic of creating the virtualenv outside the directory is due to not deploying the virtualenv when deploying the gcloud app, but there is no way to exclude it? If I'm working with vs code, I think that the virtualenv should be in the same folder where is the project.

Thanks for the help, my first question in stackoverflow!

Body:
I recommend you keep the venv distinct from the project's sources (i.e. anything you'd like manage through source control).

I generally favor:

mkdir -p ${PROJECT}/python ${PROJECT}/venv
tree -L 1 ${PROJECT}
${PROJECT}
├── python
└── venv

This keeps the project together but permits me to whack ${PROJECT}/venv as I wish and it does not taint the code that gets deployed to e.g. App Engine.

I didn't see much of an inconsistency in the Google-published guidance.

You want to ensure that the venv directory is not deployed to App Engine.


问:
Converting Date to other format in C#
Can any one suggest me the following:
 i> how to convert 3/12/2010 10:15 to the format Mar 12, 2010 10:15 in c#.
 ii> how to remove time part out of it(i.e after the conversion i want Mar 12, 2010

Thanks in advance.

答:
nimesh,

The String.Format function should be able to accommodate your needs (updated to reflect my comment):

```<code>string inputString = "03/12/2012";
DateTime dt = DateTime.MinValue;
try {
    dt = DateTime.Parse(inputString);
}
catch (Exception ex) {
    // handle the exception however you like.
    return;
}
string formattedDate = String.Format("{0:MMM d, yyyy}", dt);
</code>```

To avoid the above, check out TryParse:

http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx

You can format it in lots of ways:

http://www.csharp-examples.net/string-format-datetime/

Title: Converting Date to other format in C#

Body:
nimesh,

The String.Format function should be able to accommodate your needs (updated to reflect my comment):

string inputString = "03/12/2012";
DateTime dt = DateTime.MinValue;
try {
    dt = DateTime.Parse(inputString);
}
catch (Exception ex) {
    // handle the exception however you like.
    return;
}
string formattedDate = String.Format("{0:MMM d, yyyy}", dt);

To avoid the above, check out TryParse:

http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx

You can format it in lots of ways:

http://www.csharp-examples.net/string-format-datetime/


问:
Can I make a style for last level in multilevel list with CSS?
I have a large multilevel list like this:

li
{
  list-style-type: none;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><ul>
    <li>level1 item</li>
    <li>level1 item
      <ul>
        <li>level2 item</li>
        <li>level2 item
          <ul>
            <li>level3 item</li>
          </ul>
        </li>
      </ul>
    </li>
    <li>level1 item
      <ul>
        <li>level2 item</li>
        <li>level2 item</li>
      </ul>
    </li>
</ul></code>```

And I need to make a special style for items on the last level only, i.e. if item hasn't any subitems it must have a special style. I could use classes but the problem is that this list is very large and it's not mine so I can't somehow modify the list itself, I can only write the css for it (or write js code, but I don't want to do it)

答:
```<code>ul>li:last-of-type
{
  list-style-type: none;
}
</code>```

Body:
I have a large multilevel list like this:

li
{
  list-style-type: none;
}

level1 item

level1 item

level2 item

level2 item

level3 item

level1 item

level2 item

level2 item

And I need to make a special style for items on the last level only, i.e. if item hasn't any subitems it must have a special style. I could use classes but the problem is that this list is very large and it's not mine so I can't somehow modify the list itself, I can only write the css for it (or write js code, but I don't want to do it)


问:
"Extra argument" error when using CombineLatest from the Combine framework
The issue can be seen in the following playground. There are four published values that will be updated asynchronously (an image and three strings). When all four of them have been initialized or subsequently changed then the UI will need to be updated. When I try to capture this data flow using CombineLatest4 the compiler immediately objects to the fourth argument with the message Extra argument in call. (Note: the following code doesn't actually do anything since it only has a publisher, but it is sufficient to produce the error message in Playground).

```<code>import Combine
import UIKit

struct CustomerUpdates
{
    @Published var photo: UIImage!
    @Published var firstName: String!
    @Published var lastName: String!
    @Published var id: String!

    typealias customerTuple =
        (   photo: UIImage,
            firstName: String,
            lastName: String,
            id: String )
    var validatedCustomer: AnyPublisher< customerTuple, Never >
    {
        return Publishers.CombineLatest4( $photo,
                                          $firstName,
                                          $lastName,
                                          $id )
        {
            photo, firstName, lastName, id in
            if      photo == nil
                ||  firstName == nil
                ||  lastName == nil
                ||  id == nil
            {
                return nil
            }
            return ( photo!, firstName!, lastName!, id! )
        }
        .compactMap
        .return( on: RunLoop.main )
    }
}
</code>```

My question is, why does the compiler flag the fourth argument (the "id")? Apple's documentation for the CombineLatest4 generic struct says:

A publisher that receives and combines the latest elements from four
  publishers.

答:
The problem is that CombineLatest doesn't take a closure, it simply emits the latest value emitted from all of its upstreams whenever any of the upstreams emit a new value. Your closure should be supplied to compactMap instead, which is the operator that takes a closure returning an Optional and only emits a value downstream if the return value was not nil.

```<code>struct CustomerUpdates {
    @Published var photo: UIImage!
    @Published var firstName: String!
    @Published var lastName: String!
    @Published var id: String!

    typealias CustomerTuple = (photo: UIImage, firstName: String, lastName: String, id: String)
    var validatedCustomer: AnyPublisher<CustomerTuple, Never> {

        return Publishers.CombineLatest4($photo, $firstName, $lastName, $id)
            .compactMap { photo, firstName, lastName, id in
                guard let photo = photo, let firstName = firstName, let lastName = lastName, let id = id else { return nil }
                return ( photo, firstName, lastName, id)
            }
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
    }
}
</code>```

A couple of other issues unrelated to your question: there's no such operator return(on:), you need receive(on:) and you want to pass DispatchQueue.main, not RunLoop.main to be able to publish updates straight to your UI.

Type names should be UpperCamelCase in Swift, so use CustomerTuple instead of customerTuple.

Also, your properties should be Optional (var photo: UIImage?), not implicitly unwrapped optional (var photo: UIImage!).

Body:
The issue can be seen in the following playground. There are four published values that will be updated asynchronously (an image and three strings). When all four of them have been initialized or subsequently changed then the UI will need to be updated. When I try to capture this data flow using CombineLatest4 the compiler immediately objects to the fourth argument with the message Extra argument in call. (Note: the following code doesn't actually do anything since it only has a publisher, but it is sufficient to produce the error message in Playground).

import Combine
import UIKit

struct CustomerUpdates
{
    @Published var photo: UIImage!
    @Published var firstName: String!
    @Published var lastName: String!
    @Published var id: String!

    typealias customerTuple =
        (   photo: UIImage,
            firstName: String,
            lastName: String,
            id: String )
    var validatedCustomer: AnyPublisher< customerTuple, Never >
    {
        return Publishers.CombineLatest4( $photo,
                                          $firstName,
                                          $lastName,
                                          $id )
        {
            photo, firstName, lastName, id in
            if      photo == nil
                ||  firstName == nil
                ||  lastName == nil
                ||  id == nil
            {
                return nil
            }
            return ( photo!, firstName!, lastName!, id! )
        }
        .compactMap
        .return( on: RunLoop.main )
    }
}

My question is, why does the compiler flag the fourth argument (the "id")? Apple's documentation for the CombineLatest4 generic struct says:

A publisher that receives and combines the latest elements from four
  publishers.

Body:
The problem is that CombineLatest doesn't take a closure, it simply emits the latest value emitted from all of its upstreams whenever any of the upstreams emit a new value. Your closure should be supplied to compactMap instead, which is the operator that takes a closure returning an Optional and only emits a value downstream if the return value was not nil.

struct CustomerUpdates {
    @Published var photo: UIImage!
    @Published var firstName: String!
    @Published var lastName: String!
    @Published var id: String!

    typealias CustomerTuple = (photo: UIImage, firstName: String, lastName: String, id: String)
    var validatedCustomer: AnyPublisher<CustomerTuple, Never> {

        return Publishers.CombineLatest4($photo, $firstName, $lastName, $id)
            .compactMap { photo, firstName, lastName, id in
                guard let photo = photo, let firstName = firstName, let lastName = lastName, let id = id else { return nil }
                return ( photo, firstName, lastName, id)
            }
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
    }
}

A couple of other issues unrelated to your question: there's no such operator return(on:), you need receive(on:) and you want to pass DispatchQueue.main, not RunLoop.main to be able to publish updates straight to your UI.

Type names should be UpperCamelCase in Swift, so use CustomerTuple instead of customerTuple.

Also, your properties should be Optional (var photo: UIImage?), not implicitly unwrapped optional (var photo: UIImage!).


问:
hiding overlay after some time just like standard video player
i am making a custom video player in which there is an overlay containing the controls of the video player

my player starts to work in full length and height.

now i want to hide the overlay after 5 seconds i stop the mouse over.

now the problem is that when the below function mouse over in .ts file is called the synchronization of the timer is harmed.

so if i move my mouse continuously the overlay starts to flicker.

please provide me the solution to the problem.

following is my html code

```<code><div class="video-container" #videoFullscreen>
    <div class="video-wrapper" mouse-move>
      <video class="video video-js" data-dashjs-player  id="myVideo"  autoplay #videoPlayer>
        <source src="{{ videoSource }}" type="video/mp4" />
      </video>

      <!-- overlay -->
      <div class="overlay" [class.hideOverlay]="hideTop">
        <!-- top controls  -->
          .
          .
          <!-- lower controls  -->

        </div>
      </div>
</code>```

this is my type script code

```<code>@HostListener('document:mousemove', [ '$event' ]) //fuction to display and hide element sue to mouseover
    onMouseMove($event) {
            this.hideTop = false;
            setTimeout(() => {
                this.hideTop = true;
            }, 5000);
    }
</code>```

this is my css code :

```<code>.overlay {
    display: flex;
}
.hideOverlay {
    display:none;
}
</code>```

please help me to solve this problem.

答:
Store the lastHover time and compare against it.</p>

```<code>private lastHover = 0;
@HostListener(...)
onMouseMove($event) {
    this.lastHover = new Date().getTime()
    This.hideTop = true;
    setTimeout( () => {
        ...
        if(lastHover + 5000 < new Date().getTime()) {
            This.hideTop = true;
        }
    }, 5000)
}
</code>```

Body:
i am making a custom video player in which there is an overlay containing the controls of the video player

my player starts to work in full length and height.

now i want to hide the overlay after 5 seconds i stop the mouse over.

now the problem is that when the below function mouse over in .ts file is called the synchronization of the timer is harmed.

so if i move my mouse continuously the overlay starts to flicker.

please provide me the solution to the problem.

following is my html code

      <video class="video video-js" data-dashjs-player  id="myVideo"  autoplay #videoPlayer>
        <source src="{{ videoSource }}" type="video/mp4" />
      </video>

          .
          .

this is my type script code

@HostListener('document:mousemove', [ '$event' ]) //fuction to display and hide element sue to mouseover
    onMouseMove($event) {
            this.hideTop = false;
            setTimeout(() => {
                this.hideTop = true;
            }, 5000);
    }

this is my css code :

.overlay {
    display: flex;
}
.hideOverlay {
    display:none;
}

please help me to solve this problem.

Body:
Store the lastHover time and compare against it.

private lastHover = 0;
@HostListener(...)
onMouseMove($event) {
    this.lastHover = new Date().getTime()
    This.hideTop = true;
    setTimeout( () => {
        ...
        if(lastHover + 5000 < new Date().getTime()) {
            This.hideTop = true;
        }
    }, 5000)
}


问:
Why isn't my updated .gitignore working for files that are being tracked?
I have the following .gitignore file

```<code># file named .gitignore

system/application/config/database.php
system/application/config/config.php
system/logs
modules/recaptcha/config/*
</code>```

However when I add any changes in config and recapcha.php, git status warns me as following.
When I add any changes to database.php. it does not show it in status

```<code>shin@shin-Latitude-E5420:/var/www/myapp$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   modules/recaptcha/config/recaptcha.php
#   modified:   system/application/config/config.php
#
no changes added to commit (use "git add" and/or "git commit -a")
</code>```

How can I fix this?

I am using git version 1.7.5.1 on Ubuntu 11.04

答:
I'm guessing yout .gitignore is not in the root of your working tree.

If you put a .gitignore in the same directory as system/application/config/config.php you can just use

```<code>echo config.php >> system/application/config/.gitignore
</code>```

The paths are relative to the current directory (or: .gitignore is a per-directory exclude/include file).

See man git-ignore

Body:
I have the following .gitignore file

# file named .gitignore

system/application/config/database.php
system/application/config/config.php
system/logs
modules/recaptcha/config/*

However when I add any changes in config and recapcha.php, git status warns me as following.
When I add any changes to database.php. it does not show it in status

shin@shin-Latitude-E5420:/var/www/myapp$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   modules/recaptcha/config/recaptcha.php
#   modified:   system/application/config/config.php
#
no changes added to commit (use "git add" and/or "git commit -a")

How can I fix this?

I am using git version 1.7.5.1 on Ubuntu 11.04

Body:
I'm guessing yout .gitignore is not in the root of your working tree.

If you put a .gitignore in the same directory as system/application/config/config.php you can just use

echo config.php >> system/application/config/.gitignore

The paths are relative to the current directory (or: .gitignore is a per-directory exclude/include file).

See man git-ignore


问:
Return 2 objects using an IIFE
I'm trying to return 2 objects using an IIFE. I cant find whats wrong here.</p>

```<code>var UIController = (function(){

    return{
        getMinput: function(){
            return {
            mstaff1: document.querySelector('#mstaff1').value,
            mstaff2: document.querySelector('#mstaff2').value,
            mpda: document.querySelector('#mpda').value,
            mpos: document.querySelector('#mpos').value,
            mcash: document.querySelector('#mcash').value,
            mtotal: document.querySelector('#mtotal').value
            };
        }

        getMinput: function(){
            return {
            mstaff1: document.querySelector('#mstaff1').value,
            mstaff2: document.querySelector('#mstaff2').value,
            mpda: document.querySelector('#mpda').value,
            mpos: document.querySelector('#mpos').value,
            mcash: document.querySelector('#mcash').value,
            mtotal: document.querySelector('#mtotal').value
            };
        }
    };

})();
</code>```

答:
You cannot have two returns from a single run of a function. That's physically impossible.

But you can return an array of values.

```<code>     var UIController = (function ... return [ /*whatever porcesing*/ , /*second result */ ]; .. })();
</code>```

Title: Return 2 objects using an IIFE

Body:
I'm trying to return 2 objects using an IIFE. I cant find whats wrong here.

var UIController = (function(){

    return{
        getMinput: function(){
            return {
            mstaff1: document.querySelector('#mstaff1').value,
            mstaff2: document.querySelector('#mstaff2').value,
            mpda: document.querySelector('#mpda').value,
            mpos: document.querySelector('#mpos').value,
            mcash: document.querySelector('#mcash').value,
            mtotal: document.querySelector('#mtotal').value
            };
        }

        getMinput: function(){
            return {
            mstaff1: document.querySelector('#mstaff1').value,
            mstaff2: document.querySelector('#mstaff2').value,
            mpda: document.querySelector('#mpda').value,
            mpos: document.querySelector('#mpos').value,
            mcash: document.querySelector('#mcash').value,
            mtotal: document.querySelector('#mtotal').value
            };
        }
    };

})();

Body:
You cannot have two returns from a single run of a function. That's physically impossible.

But you can return an array of values.

     var UIController = (function ... return [ /*whatever porcesing*/ , /*second result */ ]; .. })();


问:
Unity android build error after upload project to new version
i have a problem, so i moved the unity project from version 2018.2.20f1 to version 2019.1.9f1 which has "andorid support something installed" and wanted to build a game for android, but i have such problems:
(I have JDK and SDK installed together with unity)
photos:

installed with unity

Errors:

答: Try to change your project folder so that it contain only ASCII characters, regular Arabic letters, for ex. "MyProject" and see if that helps.</p>


问:
R lubridate: Apply helper to dataframe
I have a dataframe of times looking like this:

```<code>library(lubridate)

times <- structure(list(exp1 = c("17:19:04 \r", "17:28:53 \r", "17:38:44 \r"),
                        exp2 = c("17:22:04 \r", "17:31:53 \r", "17:41:45 \r")),
                        row.names = c(NA, 3L), class = "data.frame")
</code>```

I want to convert the times in more convenient date-time objects, which I will do with the hms() helper function from the lubridate package.

Running hms() on one column of my dataframe works like a charm:

```<code>hms(times[,1])
</code>```

[1] "17H 19M 4S"  "17H 28M 53S" "17H 38M 44S"

Great, surely I can just apply() on my whole dataframe then.

```<code>apply(times, 2, hms)
</code>```

Which gives a weird dataframe with some integers, definitely not what I am expecting.

What is the right way to convert all of my times dataframe with the hms() function?

答:
Instead of apply, can use lapply as apply converts to matrix and it wouln't hold the attributes created by hms

```<code>library(lubridate)
times[] <- lapply(times, hms)
str(times)
#'data.frame':  3 obs. of  2 variables:
# $ exp1:Formal class 'Period' [package "lubridate"] with 6 slots
#  .. ..@ .Data : num  4 53 44
#  .. ..@ year  : num  0 0 0
#  .. ..@ month : num  0 0 0
#  .. ..@ day   : num  0 0 0
#  .. ..@ hour  : num  17 17 17
#  .. ..@ minute: num  19 28 38
# $ exp2:Formal class 'Period' [package "lubridate"] with 6 slots
#  .. ..@ .Data : num  4 53 45
#  .. ..@ year  : num  0 0 0
#  .. ..@ month : num  0 0 0
#  .. ..@ day   : num  0 0 0
#  .. ..@ hour  : num  17 17 17
#  .. ..@ minute: num  22 31 41
</code>```

With the devel version of dplyr, we can use mutate with across

```<code>library(dplyr)
times %>%
    mutate(across(everything(), hms))
</code>```

Title: R lubridate: Apply helper to dataframe

Body:
I have a dataframe of times looking like this:

library(lubridate)

times <- structure(list(exp1 = c("17:19:04 \r", "17:28:53 \r", "17:38:44 \r"),
                        exp2 = c("17:22:04 \r", "17:31:53 \r", "17:41:45 \r")),
                        row.names = c(NA, 3L), class = "data.frame")

I want to convert the times in more convenient date-time objects, which I will do with the hms() helper function from the lubridate package.

Running hms() on one column of my dataframe works like a charm:

hms(times[,1])

[1] "17H 19M 4S"  "17H 28M 53S" "17H 38M 44S"

Great, surely I can just apply() on my whole dataframe then.

apply(times, 2, hms)

Which gives a weird dataframe with some integers, definitely not what I am expecting.

What is the right way to convert all of my times dataframe with the hms() function?

Body:
Instead of apply, can use lapply as apply converts to matrix and it wouln't hold the attributes created by hms

library(lubridate)
times[] <- lapply(times, hms)
str(times)
#'data.frame':  3 obs. of  2 variables:
# $ exp1:Formal class 'Period' [package "lubridate"] with 6 slots
#  .. ..@ .Data : num  4 53 44
#  .. ..@ year  : num  0 0 0
#  .. ..@ month : num  0 0 0
#  .. ..@ day   : num  0 0 0
#  .. ..@ hour  : num  17 17 17
#  .. ..@ minute: num  19 28 38
# $ exp2:Formal class 'Period' [package "lubridate"] with 6 slots
#  .. ..@ .Data : num  4 53 45
#  .. ..@ year  : num  0 0 0
#  .. ..@ month : num  0 0 0
#  .. ..@ day   : num  0 0 0
#  .. ..@ hour  : num  17 17 17
#  .. ..@ minute: num  22 31 41

With the devel version of dplyr, we can use mutate with across

library(dplyr)
times %>%
    mutate(across(everything(), hms))


问:
Removing all properties from a object
I have this Javascript object.

```<code>req.session
</code>```

In my code I add properties to this object. These properties can be other objects, arrays, or just plain strings.

```<code>req.session.savedDoc = someObject;
req.session.errors = ['someThing', 'anotherThing', 'thirdThing'];
req.session.message = 'someString'
</code>```

If I later would like to erase all added properties of this object, what is the easiest/best way?

There must be a better way than this?

```<code>// Delete all session values
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;
</code>```

答:
The naive object = {} method is okay for vanilla Object, but it deletes prototypes of custom objects.

This method produces an empty object that preserves prototypes, using Object.getPrototypeOf() and Object.create():

    emptyObj = Object.create(Object.getPrototypeOf(obj), {});
```

<p>Example:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>class Custom extends Object {
  custom() {}
}

let custom = new Custom();
custom.foo = "bar";
console.log(custom.constructor.name, custom);
// Custom {"foo": "bar"}

// naive method:
let objVanilla = {}
console.log(objVanilla.constructor.name, objVanilla);
// Object {}

// safe method:
objSafe = Object.create(Object.getPrototypeOf(custom), {});
console.log(objSafe.constructor.name, objSafe);
// Custom {}</code>```

Title: Removing all properties from a object

Body:
I have this Javascript object.

req.session

In my code I add properties to this object. These properties can be other objects, arrays, or just plain strings.

req.session.savedDoc = someObject;
req.session.errors = ['someThing', 'anotherThing', 'thirdThing'];
req.session.message = 'someString'

If I later would like to erase all added properties of this object, what is the easiest/best way?

There must be a better way than this?

// Delete all session values
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;

Body:
The naive object = {} method is okay for vanilla Object, but it deletes prototypes of custom objects.

This method produces an empty object that preserves prototypes, using Object.getPrototypeOf() and Object.create():

    emptyObj = Object.create(Object.getPrototypeOf(obj), {});

Example:

class Custom extends Object {
  custom() {}
}

let custom = new Custom();
custom.foo = "bar";
console.log(custom.constructor.name, custom);
// Custom {"foo": "bar"}

// naive method:
let objVanilla = {}
console.log(objVanilla.constructor.name, objVanilla);
// Object {}

// safe method:
objSafe = Object.create(Object.getPrototypeOf(custom), {});
console.log(objSafe.constructor.name, objSafe);
// Custom {}


问:
Get value from a XML
I have a XML .How to get CustomerSet value from this ?</p>

```<code><a:CreditCards>
 <a:CreditCard>
  <a:AccountNumber>1234XXXXXX23XXXX</a:AccountNumber>
 <a:ExtendedInfo>
  <a:CustomerSet>RC808687</a:CustomerSet>
 </a:ExtendedInfo>
 </a:CreditCard>
<a:CreditCards>
</code>```

答:
Try using XPath,
To get CustomerSet value the xpath would be /CreditCards/CreditCard/ExtendedInfo/CustomerSet

Title: Get value from a XML

Body:
I have a XML .How to get CustomerSet value from this ?

  1234XXXXXX23XXXX

  RC808687


问:
Could not find a version that satisfies the requirement <package>
I'm installing several Python packages in Ubuntu 12.04 using the following requirements.txt file:

```<code>numpy>=1.8.2,<2.0.0
matplotlib>=1.3.1,<2.0.0
scipy>=0.14.0,<1.0.0
astroML>=0.2,<1.0
scikit-learn>=0.14.1,<1.0.0
rpy2>=2.4.3,<3.0.0
</code>```

and these two commands:

```<code>$ pip install --download=/tmp -r requirements.txt
$ pip install --user --no-index --find-links=/tmp -r requirements.txt
</code>```

(the first one downloads the packages and the second one installs them).

The process is frequently stopped with the error:

```<code>  Could not find a version that satisfies the requirement <package> (from matplotlib<2.0.0,>=1.3.1->-r requirements.txt (line 2)) (from versions: )
No matching distribution found for <package> (from matplotlib<2.0.0,>=1.3.1->-r requirements.txt (line 2))
</code>```

which I fix manually with:

```<code>pip install --user <package>
</code>```

and then run the second pip install command again.

But that only works for that particular package. When I run the second pip install command again, the process is stopped now complaining about another required package and I need to repeat the process again, ie: install the new required package manually (with the command above) and then run the second pip install command.

So far I've had to manually install six, pytz, nose, and now it's complaining about needing mock.

Is there a way to tell pip to automatically install all needed dependencies so I don't have to do it manually one by one?

Add: This only happens in Ubuntu 12.04 BTW. In Ubuntu 14.04 the pip install commands applied on the requirements.txt file work without issues.

答:
If you facing this issue at the workplace. This might be the solution for you.</p>

```<code>pip install -U <package_name> --user --proxy=<your proxy>
</code>```

Body:
I'm installing several Python packages in Ubuntu 12.04 using the following requirements.txt file:

numpy>=1.8.2,<2.0.0
matplotlib>=1.3.1,<2.0.0
scipy>=0.14.0,<1.0.0
astroML>=0.2,<1.0
scikit-learn>=0.14.1,<1.0.0
rpy2>=2.4.3,<3.0.0

and these two commands:

$ pip install --download=/tmp -r requirements.txt
$ pip install --user --no-index --find-links=/tmp -r requirements.txt

(the first one downloads the packages and the second one installs them).

The process is frequently stopped with the error:

  Could not find a version that satisfies the requirement <package> (from matplotlib<2.0.0,>=1.3.1->-r requirements.txt (line 2)) (from versions: )
No matching distribution found for <package> (from matplotlib<2.0.0,>=1.3.1->-r requirements.txt (line 2))

which I fix manually with:

pip install --user <package>

and then run the second pip install command again.

But that only works for that particular package. When I run the second pip install command again, the process is stopped now complaining about another required package and I need to repeat the process again, ie: install the new required package manually (with the command above) and then run the second pip install command.

So far I've had to manually install six, pytz, nose, and now it's complaining about needing mock.

Is there a way to tell pip to automatically install all needed dependencies so I don't have to do it manually one by one?

Add: This only happens in Ubuntu 12.04 BTW. In Ubuntu 14.04 the pip install commands applied on the requirements.txt file work without issues.

Body:
If you facing this issue at the workplace. This might be the solution for you.

pip install -U <package_name> --user --proxy=<your proxy>


问:
AlertDialog with ListView inside it cannot be dismissed?
I have a ListView inside an AlertDialog like this:

The code:

```<code>import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btnDialog;
    String[] listData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnDialog = (Button) findViewById(R.id.btnShowDialog);
        btnDialog.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        if (id == R.id.btnShowDialog){
            fetchData();
        }
    }

    public void fetchData(){
        RequestQueue queue = Volley.newRequestQueue(this);
        String URL ="https://jsonplaceholder.typicode.com/users";

        StringRequest dataRequest = new StringRequest(Request.Method.GET, URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONArray jsoArray = new JSONArray(response);
                            int len = jsoArray.length();

                            listData = new String[len];

                            for (int x = 0; x < len; x++){
                                JSONObject obj = jsoArray.getJSONObject(x);
                                listData[x] = obj.getString("name");

                                AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
                                LayoutInflater inflater = getLayoutInflater();
                                View convertView = (View) inflater.inflate(R.layout.listdialog, null);
                                alertDialog.setView(convertView);
                                alertDialog.setTitle("List");
                                ListView lv = (ListView) convertView.findViewById(R.id.listView1);
                                ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, listData);
                                lv.setAdapter(adapter);
                                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                    @Override
                                    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                                        Toast.makeText(getApplicationContext(), "You picked: "+listData[position], Toast.LENGTH_SHORT).show();
                                    }
                                });
                                alertDialog.show();
                            }
                        }
                        catch (JSONException je){
                            Toast.makeText(getApplicationContext(), "JSON error: "+je.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
               Toast.makeText(getApplicationContext(), "Error...", Toast.LENGTH_SHORT).show();
            }
        });

        queue.add(dataRequest);
    }
}
</code>```

Parsing the JSON and displaying it with ListView works fine.
But if you press the back button, the AlertDialog will not be dismissed (the repo is here). Normally, it should. Why?

答:
Setting setCancelable(true) attribute to your dialog should make the work.

Just before showing your dialog set this flags as below.

```<code>     AlertDialog dialog = alertDialog.create();
     dialog.setCancelable(true);
     dialog.show();
</code>```

If you want to close it only on outside dialog touch and not back button click then you can just set

```<code>     dialog.setCanceledOnTouchOutside(true);
</code>```

Regards!

Body:
I have a ListView inside an AlertDialog like this:

The code:

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btnDialog;
    String[] listData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnDialog = (Button) findViewById(R.id.btnShowDialog);
        btnDialog.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        if (id == R.id.btnShowDialog){
            fetchData();
        }
    }

    public void fetchData(){
        RequestQueue queue = Volley.newRequestQueue(this);
        String URL ="https://jsonplaceholder.typicode.com/users";

        StringRequest dataRequest = new StringRequest(Request.Method.GET, URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONArray jsoArray = new JSONArray(response);
                            int len = jsoArray.length();

                            listData = new String[len];

                            for (int x = 0; x < len; x++){
                                JSONObject obj = jsoArray.getJSONObject(x);
                                listData[x] = obj.getString("name");

                                AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
                                LayoutInflater inflater = getLayoutInflater();
                                View convertView = (View) inflater.inflate(R.layout.listdialog, null);
                                alertDialog.setView(convertView);
                                alertDialog.setTitle("List");
                                ListView lv = (ListView) convertView.findViewById(R.id.listView1);
                                ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, listData);
                                lv.setAdapter(adapter);
                                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                    @Override
                                    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                                        Toast.makeText(getApplicationContext(), "You picked: "+listData[position], Toast.LENGTH_SHORT).show();
                                    }
                                });
                                alertDialog.show();
                            }
                        }
                        catch (JSONException je){
                            Toast.makeText(getApplicationContext(), "JSON error: "+je.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
               Toast.makeText(getApplicationContext(), "Error...", Toast.LENGTH_SHORT).show();
            }
        });

        queue.add(dataRequest);
    }
}

Parsing the JSON and displaying it with ListView works fine.
But if you press the back button, the AlertDialog will not be dismissed (the repo is here). Normally, it should. Why?

Body:
Setting setCancelable(true) attribute to your dialog should make the work.

Just before showing your dialog set this flags as below.

     AlertDialog dialog = alertDialog.create();
     dialog.setCancelable(true);
     dialog.show();

If you want to close it only on outside dialog touch and not back button click then you can just set

     dialog.setCanceledOnTouchOutside(true);

Regards!


问:
I have problem when deploy my laravel on herkou (Mixed Content)
Hello …  l am finish Building website using Laravel and jQuery and bootstrap it's working good in local but when I upload to Heroku  the file jQuery and bootstrap not working … it's work in local using http but in Heroku its need https its not working but when write http substitute of https it's working good like local and display Not Secure .. now any body know how can i allow website using https in Heroku or How can selection this problem

答:
Had this issue myself awhile back, there are a few options and some are more heavy handed than others. If you want to gauruntee that everything is always https no exceptions first update your APP_URL to 'https://example.com' then in the boot method of your AppServiceProvider add Url::forceScheme('https');

The less heavy handed option is to find all of the places you use the asset() helper and change it to secure_asset instead. The asset helper should use your APP_URL to know the request is https but in my experience I couldn't rely on that so use secure_asset to make sure


问:
IE Stops Script Execution Using Reference to console.log/error/warn/info
If you get a reference to one of the console.log (console.error console.warn console.info) functions in IE 11 and try to call it, it blows up and stops script execution when not using F12 dev tools.

```<code>const logFunc = console.log;
logFunc('do some logging'); <-- stops executing further scripts here
</code>```

If you have dev tools showing, it works fine. So the only way to debug is the old-fashioned alert approach.

答:
IE must do some optimizations when you make calls to console log functions when not using their dev tools. But you can call them directly fine, and it won't stop execution:

```<code>console.log('log the thing');
</code>```

But if you get a reference, it fails. So the workaround is to not use references to those functions and always call them directly. You can create wrapper functions that do this.

Body:
If you get a reference to one of the console.log (console.error console.warn console.info) functions in IE 11 and try to call it, it blows up and stops script execution when not using F12 dev tools.

const logFunc = console.log;
logFunc('do some logging'); <-- stops executing further scripts here

If you have dev tools showing, it works fine. So the only way to debug is the old-fashioned alert approach.

Body:
IE must do some optimizations when you make calls to console log functions when not using their dev tools. But you can call them directly fine, and it won't stop execution:

console.log('log the thing');

But if you get a reference, it fails. So the workaround is to not use references to those functions and always call them directly. You can create wrapper functions that do this.


问:
Leaflet map is going blank when zooming more than 18
I'm using leaflet and her maps API, the problem is when I zoom more than 18x, the map goes blank. I added the maxNativeZoom but no success. the max zoom supported by here maps is 20 (source :  docs online)

```<code>    const here = {
  apiKey:'API_Key'
}
const style = 'hybrid.day';

const hereTileUrl = `https://2.aerial.maps.ls.hereapi.com/maptile/2.1/maptile/newest/${style}/{z}/{x}/{y}/512/jpg?apiKey=${here.apiKey}&ppi=500`;

const map = L.map('map', {
   center: [33.288410, -8.345090],
   zoom: 16,
  maxZoom: 20,
  maxNativeZoom: 20,
    // maxZoom: 22,
   layers: [L.tileLayer(hereTileUrl)]
});
map.attributionControl.addAttribution('© HERE 2019');
map.on('zoomend', showZoomLevel);
    showZoomLevel();
       function showZoomLevel() {
      document.getElementById('zoom').innerHTML = map.getZoom();
    }
//alert(map.getMaxZoom());
</code>```

https://jsfiddle.net/b73t0oe1/

答:
For your objective, you should use options maxZoom (and maxNativeZoom if necessary) on your Leaflet Tile Layer, instead of on your map.

L.tileLayer(hereTileUrl, {
  maxZoom: 20,
  maxNativeZoom: 19
})
```

Updated jsfiddle: https://jsfiddle.net/7xnv0c1a/
(Your tile source maxNativeZoom seems really to be 19, at least in the area you start your map at)

Body:
I'm using leaflet and her maps API, the problem is when I zoom more than 18x, the map goes blank. I added the maxNativeZoom but no success. the max zoom supported by here maps is 20 (source :  docs online)

    const here = {
  apiKey:'API_Key'
}
const style = 'hybrid.day';

const hereTileUrl = `https://2.aerial.maps.ls.hereapi.com/maptile/2.1/maptile/newest/${style}/{z}/{x}/{y}/512/jpg?apiKey=${here.apiKey}&ppi=500`;

const map = L.map('map', {
   center: [33.288410, -8.345090],
   zoom: 16,
  maxZoom: 20,
  maxNativeZoom: 20,
    // maxZoom: 22,
   layers: [L.tileLayer(hereTileUrl)]
});
map.attributionControl.addAttribution('© HERE 2019');
map.on('zoomend', showZoomLevel);
    showZoomLevel();
       function showZoomLevel() {
      document.getElementById('zoom').innerHTML = map.getZoom();
    }
//alert(map.getMaxZoom());

https://jsfiddle.net/b73t0oe1/

Body:
For your objective, you should use options maxZoom (and maxNativeZoom if necessary) on your Leaflet Tile Layer, instead of on your map.

L.tileLayer(hereTileUrl, {
  maxZoom: 20,
  maxNativeZoom: 19
})

Updated jsfiddle: https://jsfiddle.net/7xnv0c1a/
(Your tile source maxNativeZoom seems really to be 19, at least in the area you start your map at)


问:
How to get the distance between 2 balls / objects?
I'm making a game with balls : </p>

```<code>class Ball {

    constructor(x, y, vx, vy, radius, r, g, b) {
        this.x = x;
        this.y = y;
        this.vx = vx;
        this.vy = vy;
        this.radius = radius;
        this.r = r;
        this.g = g;
        this.b = b;

    }

    Draw() {
        this.x = this.x + this.vx*frametime;
        this.y = this.y + this.vy*frametime;
        context.fillStyle = "rgb(" + this.r + ", " + this.g + ", " + this.b + ")"
        context.beginPath();
        context.arc(this.x, this.y, this.radius, 0, Math.PI*2);
        context.closePath();
        context.fill();
</code>```

<p>And I would like to have the distance between 2 balls... How to do this ? </p>

答:
Use this inside your class Ball :</p>

```<code>Distance(ball) {
  var distance = Math.pow(this.x - ball.x, 2) + Math.pow(this.y - ball.y, 2);
  return Math.sqrt(distance);
}
</code>```

Body:
I'm making a game with balls :

class Ball {

    constructor(x, y, vx, vy, radius, r, g, b) {
        this.x = x;
        this.y = y;
        this.vx = vx;
        this.vy = vy;
        this.radius = radius;
        this.r = r;
        this.g = g;
        this.b = b;

    }

    Draw() {
        this.x = this.x + this.vx*frametime;
        this.y = this.y + this.vy*frametime;
        context.fillStyle = "rgb(" + this.r + ", " + this.g + ", " + this.b + ")"
        context.beginPath();
        context.arc(this.x, this.y, this.radius, 0, Math.PI*2);
        context.closePath();
        context.fill();

And I would like to have the distance between 2 balls... How to do this ?

Body:
Use this inside your class Ball :

Distance(ball) {
  var distance = Math.pow(this.x - ball.x, 2) + Math.pow(this.y - ball.y, 2);
  return Math.sqrt(distance);
}


问:
SimpleHTTPServer not found python3
I'm trying to write a simple server in python. So after watching tutorial, I'm trying to import a few modules.

```<code>from http.server import HTTPServer
from http.server import SimpleHTTPServer
</code>```

As the doc says, it has been moved, that's why i'm doing so.

But it gives me this error : from http.server import SimpleHTTPServer
ImportError: cannot import name 'SimpleHTTPServer'

And without SimpleHTTPServer I can't use SimpleHTTPRequestHandler, as it is defined in SimpleHTTPServer.SimpleHTTPRequestHandler.

How can I resolve this ?

答:
The SimpleHTTPServer module was moved to be the module http.server. So the command is:

```<code>python3 -m http.server
</code>```

Also, the new SimpleHTTPRequestHandler object is BaseHTTPRequestHandler.

Title: SimpleHTTPServer not found python3

Body:
I'm trying to write a simple server in python. So after watching tutorial, I'm trying to import a few modules.

from http.server import HTTPServer
from http.server import SimpleHTTPServer

As the doc says, it has been moved, that's why i'm doing so.

But it gives me this error : from http.server import SimpleHTTPServer
ImportError: cannot import name 'SimpleHTTPServer'

And without SimpleHTTPServer I can't use SimpleHTTPRequestHandler, as it is defined in SimpleHTTPServer.SimpleHTTPRequestHandler.

How can I resolve this ?

Body:
The SimpleHTTPServer module was moved to be the module http.server. So the command is:

python3 -m http.server

Also, the new SimpleHTTPRequestHandler object is BaseHTTPRequestHandler.


问:
Logging Data to Azure Application Insights from Docker container
I have a custom Docker image that uses Windows Servercore as base image..

I have written commands in Dockerfile , which will perform a git pull when my docker image is pulled from Azure Container Registry

Git Repository contains Application Insights DLL and a powershell script.
Script uses DLL to create a object of Telemetry and pushes a Dummy Data to App Insights using Trackevent(). I have set this file as Entrypoint in my DockerFile.

So When I Run the Instance/Perform a Docker Pull, The Script runs. The Script runs completely(I have written Write-Host at different parts of Script to confirm this) but the Data is not logged into Azure Application Insights.

when i tried to run the script locally , it does Log the Data to App Insights.
Am I missing something here?

```<code>$eventprops = @{ Name = "Test" };
$jsonevent=ConvertTo-Json $eventprops;
$client.TrackEvent($jsonevent,$null)
# $client is a Telemetry object
</code>```

答:
Application Insights usually sends data out in batches only. If your script shuts down directly after the last logging, it might not have sent this out yet. To solve, you can manually flush. Just add at the end:

$client.Flush()

See here for a complete example.

Body:
I have a custom Docker image that uses Windows Servercore as base image..

I have written commands in Dockerfile , which will perform a git pull when my docker image is pulled from Azure Container Registry

Git Repository contains Application Insights DLL and a powershell script.
Script uses DLL to create a object of Telemetry and pushes a Dummy Data to App Insights using Trackevent(). I have set this file as Entrypoint in my DockerFile.

So When I Run the Instance/Perform a Docker Pull, The Script runs. The Script runs completely(I have written Write-Host at different parts of Script to confirm this) but the Data is not logged into Azure Application Insights.

when i tried to run the script locally , it does Log the Data to App Insights.
Am I missing something here?

$eventprops = @{ Name = "Test" };
$jsonevent=ConvertTo-Json $eventprops;
$client.TrackEvent($jsonevent,$null)
# $client is a Telemetry object


问:
Javascript insert array in array
Source from wi2l.de/sof.html

var x = -1;
var a = new Array(9);
var i = new Array(2);

x = x + 1;
a[x] = ["a", "b"];
x = x + 1;
a[x] = ["c", "d"];
i[0] = "e";
i[1] = "f";
x = x + 1;
a[x] = i;
i[0] = "g";
i[1] = "h";
x = x + 1;
a[x] = i;

console.log(a[1] + " " + a[2] + " " + a[3]);```

result is c,d g,h g,h but should be c,d e,f g,h.

答:
The code does what it is expected to do in the contents of array a is [["a","b"],["c","d"],i,i]

Because you change the value of i to [g,h] you change it in both places. If what you wanted to do was create a copy of the array you could change

```<code>x=x+1;
a[x]=i;
</code>```

to:

```<code>i[0] = "e";
i[1] = "f";
x = x + 1;
a[x] = [...i]; //creates a new array with the contents of i
i[0] = "g";
i[1] = "h";
x = x + 1;
a[x] = i;
</code>```

Doing this results in [["a","b"],["c","d"],["e","f"],i]

Title: Javascript insert array in array

Body:
Source from wi2l.de/sof.html

var x = -1;
var a = new Array(9);
var i = new Array(2);

x = x + 1;
a[x] = ["a", "b"];
x = x + 1;
a[x] = ["c", "d"];
i[0] = "e";
i[1] = "f";
x = x + 1;
a[x] = i;
i[0] = "g";
i[1] = "h";
x = x + 1;
a[x] = i;

console.log(a[1] + " " + a[2] + " " + a[3]);

result is c,d g,h g,h but should be c,d e,f g,h.

Body:
The code does what it is expected to do in the contents of array a is [["a","b"],["c","d"],i,i]

Because you change the value of i to [g,h] you change it in both places. If what you wanted to do was create a copy of the array you could change

x=x+1;
a[x]=i;

to:

i[0] = "e";
i[1] = "f";
x = x + 1;
a[x] = [...i]; //creates a new array with the contents of i
i[0] = "g";
i[1] = "h";
x = x + 1;
a[x] = i;

Doing this results in [["a","b"],["c","d"],["e","f"],i]


问:
android expandablelistview does not expand or receive click events
I can't for the life of me figure out why my ExpandableListView doesn't expand... I have used log statements in just about every click listener I can find for the ExpandableListView and it doesnt look like any of them get called.

I know there are many posts on this topic but I have read through them all and tried many things and am having no luck, hopefully I'm missing some tiny error that will be easy to spot for someone else.

Main Activity:

```<code>public class ForumListActivity extends Activity  {

    private static ArrayList<Forum> forumList;
    private static ArrayList<ArrayList<SubForum>> subForumList;
    private ExpandableListView forumListView;
    private ForumListAdapter forumListAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main_page);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        forumListView = (ExpandableListView) this.findViewById(R.id.main_page_forum_list);

        forumList = new ArrayList<Forum>();
        subForumList = new ArrayList<ArrayList<SubForum>>();
        setUpForums(this);

        forumListAdapter = new ForumListAdapter(this, forumList, subForumList);
        forumListView.setAdapter(forumListAdapter);

        forumListView.setOnGroupExpandListener(new OnGroupExpandListener(){
            @Override
            public void onGroupExpand(int groupPosition) {
                Log.d("onGroupExpand", "this works?");
                for(int i=0; i<forumListAdapter.getGroupCount(); i++) {
                    if(i != groupPosition)
                        forumListView.collapseGroup(groupPosition);
                }
            }
        });

        forumListView.setOnGroupClickListener(new OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                Log.d("onGroupClick:", "worked");
                parent.expandGroup(groupPosition);
                return true;
            }
        });
    }
</code>```

Note: the method setUpForums() just takes system arrays and puts them into forumList and subForumList

ListViewAdapter:

```<code>public class ForumListAdapter extends BaseExpandableListAdapter {

    private ArrayList<Forum> groups;
    private ArrayList<ArrayList<SubForum>> children;
    private Context ctx;

    public ForumListAdapter(Context ctx, ArrayList<Forum> groups, ArrayList<ArrayList<SubForum>> children) {
        this.ctx = ctx;
        this.groups = groups;
        this.children = children;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return children.get(groupPosition).get(childPosition);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(ctx);
            convertView = inflater.inflate(R.layout.forum_list_child_item_row, null);
        }

        SubForum currentSubForum = children.get(groupPosition).get(childPosition);
        TextView name = (TextView)convertView.findViewById(R.id.child_row_forum_title);
        TextView desc = (TextView)convertView.findViewById(R.id.child_row_forum_description);

        if (name != null)
            name.setText(currentSubForum.getName());

        if (desc != null)
            desc.setText(currentSubForum.getDescription());

        convertView.setFocusableInTouchMode(true);
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return children.get(groupPosition).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return groups.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return groups.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null)
        {
            LayoutInflater inflater = LayoutInflater.from(ctx);
            convertView = inflater.inflate(R.layout.forum_list_group_item_row, null);
        }

        Forum currentForum = (Forum) groups.get(groupPosition);
        TextView name = (TextView) convertView.findViewById(R.id.group_item_forum_title);
        //ImageView image = (ImageView) convertView.findViewById(R.id.group_item_expander_image);

        if(name != null)
            name.setText(currentForum.getName());

        /*
        if(image != null) {
            int[][] group_state_sets = {{}, {android.R.attr.state_expanded}};
            image.setVisibility(View.VISIBLE);
            int stateSetIndex = (isExpanded ? 1 : 0) ;
            Drawable drawable = image.getDrawable();
            drawable.setState(group_state_sets[stateSetIndex]);
        }
        */

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

}
</code>```

Group Layout:

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/turquoise_gradient"
    android:orientation="horizontal"
    android:paddingTop="6dip"
    android:paddingBottom="6dip"
    android:paddingLeft="6dip" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/turquoise_gradient"
        android:orientation="vertical"
        android:padding="2dip" >

        <TextView
            android:id="@+id/group_item_forum_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|left"
            android:gravity="left"
            android:paddingLeft="5dip"
            android:textColor="@color/white"
            android:textSize="16dip" />

    </LinearLayout>

    <!--
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:gravity="center|right">

        <ImageView
            android:id="@+id/group_item_expander_image"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/collapse_down" />

    </LinearLayout> -->

</LinearLayout>
</code>```

child layout:

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/turquoise_gradient"
    android:orientation="horizontal"
    android:paddingTop="6dip"
    android:paddingBottom="6dip"
    android:paddingLeft="6dip" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="2dip"
        android:background="@drawable/turquoise_gradient" >

        <TextView
            android:id="@+id/child_row_forum_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:layout_gravity="center_vertical"
            android:paddingLeft="5dip"
            android:textColor="@color/white"
            android:maxLines="1"
            android:textSize="11dip"  />

         <TextView
            android:id="@+id/child_row_forum_description"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:layout_gravity="center_vertical"
            android:paddingLeft="15dip"
            android:textColor="@color/white"
            android:maxLines="2"
            android:textSize="11dip"  />

    </LinearLayout>

</LinearLayout>
</code>```

main page layout:

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/black"
    android:orientation="vertical" >

    <ExpandableListView
        android:id="@+id/main_page_forum_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/black"
        android:divider="@color/black"
        android:dividerHeight="1dip"
        android:clickable="true" />

</LinearLayout>
</code>```

Any help you can provide is greatly appreciated!

答:
In my case I had buttons in group and child views and even setting android:focusable="false"
android:focusableInTouchMode="false" on both it didn't work.

So I had to change them from ImageButton to ImageView. The listeners for the clicks are the same. You might need to create a custom background to give the touch animation for the ImageView.

Body:
I can't for the life of me figure out why my ExpandableListView doesn't expand... I have used log statements in just about every click listener I can find for the ExpandableListView and it doesnt look like any of them get called.

I know there are many posts on this topic but I have read through them all and tried many things and am having no luck, hopefully I'm missing some tiny error that will be easy to spot for someone else.

Main Activity:

public class ForumListActivity extends Activity  {

    private static ArrayList<Forum> forumList;
    private static ArrayList<ArrayList<SubForum>> subForumList;
    private ExpandableListView forumListView;
    private ForumListAdapter forumListAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main_page);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        forumListView = (ExpandableListView) this.findViewById(R.id.main_page_forum_list);

        forumList = new ArrayList<Forum>();
        subForumList = new ArrayList<ArrayList<SubForum>>();
        setUpForums(this);

        forumListAdapter = new ForumListAdapter(this, forumList, subForumList);
        forumListView.setAdapter(forumListAdapter);

        forumListView.setOnGroupExpandListener(new OnGroupExpandListener(){
            @Override
            public void onGroupExpand(int groupPosition) {
                Log.d("onGroupExpand", "this works?");
                for(int i=0; i<forumListAdapter.getGroupCount(); i++) {
                    if(i != groupPosition)
                        forumListView.collapseGroup(groupPosition);
                }
            }
        });

        forumListView.setOnGroupClickListener(new OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                Log.d("onGroupClick:", "worked");
                parent.expandGroup(groupPosition);
                return true;
            }
        });
    }

Note: the method setUpForums() just takes system arrays and puts them into forumList and subForumList

ListViewAdapter:

public class ForumListAdapter extends BaseExpandableListAdapter {

    private ArrayList<Forum> groups;
    private ArrayList<ArrayList<SubForum>> children;
    private Context ctx;

    public ForumListAdapter(Context ctx, ArrayList<Forum> groups, ArrayList<ArrayList<SubForum>> children) {
        this.ctx = ctx;
        this.groups = groups;
        this.children = children;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return children.get(groupPosition).get(childPosition);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(ctx);
            convertView = inflater.inflate(R.layout.forum_list_child_item_row, null);
        }

        SubForum currentSubForum = children.get(groupPosition).get(childPosition);
        TextView name = (TextView)convertView.findViewById(R.id.child_row_forum_title);
        TextView desc = (TextView)convertView.findViewById(R.id.child_row_forum_description);

        if (name != null)
            name.setText(currentSubForum.getName());

        if (desc != null)
            desc.setText(currentSubForum.getDescription());

        convertView.setFocusableInTouchMode(true);
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return children.get(groupPosition).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return groups.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return groups.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null)
        {
            LayoutInflater inflater = LayoutInflater.from(ctx);
            convertView = inflater.inflate(R.layout.forum_list_group_item_row, null);
        }

        Forum currentForum = (Forum) groups.get(groupPosition);
        TextView name = (TextView) convertView.findViewById(R.id.group_item_forum_title);
        //ImageView image = (ImageView) convertView.findViewById(R.id.group_item_expander_image);

        if(name != null)
            name.setText(currentForum.getName());

        /*
        if(image != null) {
            int[][] group_state_sets = {{}, {android.R.attr.state_expanded}};
            image.setVisibility(View.VISIBLE);
            int stateSetIndex = (isExpanded ? 1 : 0) ;
            Drawable drawable = image.getDrawable();
            drawable.setState(group_state_sets[stateSetIndex]);
        }
        */

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

}

Group Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/turquoise_gradient"
    android:orientation="horizontal"
    android:paddingTop="6dip"
    android:paddingBottom="6dip"
    android:paddingLeft="6dip" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/turquoise_gradient"
        android:orientation="vertical"
        android:padding="2dip" >

        <TextView
            android:id="@+id/group_item_forum_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|left"
            android:gravity="left"
            android:paddingLeft="5dip"
            android:textColor="@color/white"
            android:textSize="16dip" />

    </LinearLayout>

</LinearLayout>

child layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/turquoise_gradient"
    android:orientation="horizontal"
    android:paddingTop="6dip"
    android:paddingBottom="6dip"
    android:paddingLeft="6dip" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="2dip"
        android:background="@drawable/turquoise_gradient" >

        <TextView
            android:id="@+id/child_row_forum_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:layout_gravity="center_vertical"
            android:paddingLeft="5dip"
            android:textColor="@color/white"
            android:maxLines="1"
            android:textSize="11dip"  />

         <TextView
            android:id="@+id/child_row_forum_description"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:layout_gravity="center_vertical"
            android:paddingLeft="15dip"
            android:textColor="@color/white"
            android:maxLines="2"
            android:textSize="11dip"  />

    </LinearLayout>

</LinearLayout>

main page layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/black"
    android:orientation="vertical" >

    <ExpandableListView
        android:id="@+id/main_page_forum_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/black"
        android:divider="@color/black"
        android:dividerHeight="1dip"
        android:clickable="true" />

</LinearLayout>

Any help you can provide is greatly appreciated!


问:
Is it possible to use Single File Vue Components in premade html files
I'm trying to create a Flask project but I wanted to use Vue as well. I've done some reading about how I can use js files and combine them into my html files and make components like that, but I want to be able to create vue files and use them in my index.html without having to generate an app.html from webpack. I'd like to be able to use a component made in a vue file inside an index.html that I'm already using in flask. Is this possible?</p>

```<code>webapp
|-- static
  |-- css
  |-- vueComponents
    |--  Hello.vue
  |-- js
  |-- templates
    |-- index.html (not generated by webpack and vue)
</code>```

答: Yes, it is, but there are some disadvantages using this approach for big projects. You can read more here. For a small size project, you can use Vue.component and render using css selectors creating a Vue instance. You can check this here</p>

Body:
I'm trying to create a Flask project but I wanted to use Vue as well. I've done some reading about how I can use js files and combine them into my html files and make components like that, but I want to be able to create vue files and use them in my index.html without having to generate an app.html from webpack. I'd like to be able to use a component made in a vue file inside an index.html that I'm already using in flask. Is this possible?

webapp
|-- static
  |-- css
  |-- vueComponents
    |--  Hello.vue
  |-- js
  |-- templates
    |-- index.html (not generated by webpack and vue)


问:
How to get a Jenkins Pipeline build to show change history (changes) for a specific branch
I am using a declarative pipeline and groovy scripts to check out my branch. I check out using the checkout step:

```<code>    [$class: 'GitSCM',
    branches: [[name: "${selectedBranch}"]],
    browser: [$class: 'BitbucketWeb', repoUrl: 'myURL'],
    doGenerateSubmoduleConfigurations: false,
    extensions:
    [[$class: 'CloneOption', noTags: false, reference: "${cloneReference}", shallow: true, timeout: 5]],
    submoduleCfg: [],
    userRemoteConfigs: [[url: "${projectDetails.repositoryAddress}"]]])
</code>```

And that works great. However when looking at the change history, it shows the history for my shared library NOT for the actual branch checked out. This means I'm getting all the history for my jenkins groovy changes, but no history for the actual solution/source being built. I cannot figure out a way to overcome this.

On my Jenkins job I see this:

```<code>Started by user Me

    Revision: 53eb41e0c05fd4cb466268947102990b2b14354e
GroovyImplementation
    Revision: 825d8201904b000f479ebc91c9d244cfb956dd85
refs/remotes/origin/releases/release-2.18
</code>```

On the "Changes" page I see changes for "GroovyImplementation" (of which there are frequently none) but I want changes for "refs/remotes/origin/releases/release-2.18" which is where the meaningful changes are.

Similarly, on the Stage View I see the number of commits for "GroovyImplementation" rather than the release branch.

How can I display checkout information for the release branch without using a multi-pipeline build?

答: The changelog is calculated by default against a previous build, you can read it here https://github.com/jenkinsci/git-plugin#changelog-extensions. If you want the changelog to be calculated against a specific branch you can configure your job explicitly by adding additional behavior Calculate changelog against a specific branch

Body:
I am using a declarative pipeline and groovy scripts to check out my branch. I check out using the checkout step:

    [$class: 'GitSCM',
    branches: [[name: "${selectedBranch}"]],
    browser: [$class: 'BitbucketWeb', repoUrl: 'myURL'],
    doGenerateSubmoduleConfigurations: false,
    extensions:
    [[$class: 'CloneOption', noTags: false, reference: "${cloneReference}", shallow: true, timeout: 5]],
    submoduleCfg: [],
    userRemoteConfigs: [[url: "${projectDetails.repositoryAddress}"]]])

And that works great. However when looking at the change history, it shows the history for my shared library NOT for the actual branch checked out. This means I'm getting all the history for my jenkins groovy changes, but no history for the actual solution/source being built. I cannot figure out a way to overcome this.

On my Jenkins job I see this:

Started by user Me

    Revision: 53eb41e0c05fd4cb466268947102990b2b14354e
GroovyImplementation
    Revision: 825d8201904b000f479ebc91c9d244cfb956dd85
refs/remotes/origin/releases/release-2.18

On the "Changes" page I see changes for "GroovyImplementation" (of which there are frequently none) but I want changes for "refs/remotes/origin/releases/release-2.18" which is where the meaningful changes are.

Similarly, on the Stage View I see the number of commits for "GroovyImplementation" rather than the release branch.

How can I display checkout information for the release branch without using a multi-pipeline build?


问:
Display data after subscribe from firebase snapshot
I'm struggling with rxjs.. I would like to sort an array coming from my subscription.
But the sort never play..
SO first I tried to display userBirthdayDate from service but didn't work like expected.

this is my service

```<code> getAllUsers() {
    return new Promise((resolve, reject) => {
      firebase
        .database()
        .ref()
        .child('users')
        .on(
          'value',
          snapshot => {
            resolve(
              snapshot.forEach(childSnapshot => {
                this.usersBirthday = childSnapshot.val()
                  ? childSnapshot.val()
                  : [];
                this.emitBirthday();
              })
            );
          },
          error => {
            reject(error);
          }
        );
    });
  }
</code>```

my component.ts

```<code>export class WidgetBirthdayComponent implements OnInit {
  users: User[];
  usersBirthdayDate = [];
  usersSubscription: Subscription;

  constructor(private userService: UsersService) {}

  ngOnInit() {
    // this.usersSubscription = this.userService.birthdaySubject.subscribe(
    //   test => {
    //     this.usersBirthdayDate.push(test);
    //   }
    // );
    // this.userService.emitBirthday();
    // this.userService.getAllUsers();

    const myArray = [
      {
        name: "Joel",
        birthdayDate: "Wednesday, November 25, 1992"
      },
      {
        name: "Sarah",
        birthdayDate: "Thursday, April 16, 1992"
      },
      {
        name: "Beverly",
        birthdayDate: "Thursday, February 26, 1998"
      }
    ];

    myArray.sort(function compare(a, b) {
      const now = new Date();
      const dateA = new Date(a.birthdayDate);
      dateA.setFullYear(now.getFullYear());
      if (dateA.getTime() - now.getTime() < 0) {
        dateA.setFullYear(now.getFullYear() + 1);
      }
      const dateB = new Date(b.birthdayDate);
      dateA.setFullYear(new Date().getFullYear());
      dateA.setFullYear(now.getFullYear());
      if (dateB.getTime() - now.getTime() < 0) {
        dateB.setFullYear(now.getFullYear() + 1);
      }
      return dateA.getTime() - dateB.getTime();
    });
    console.log(myArray);
  }
</code>```

So I tried with strong data and my function sort is working well.. but I can"t use usersBirthdayDate[] on it.. PLease need help :)

答:
In case you tried to sort the array outside the subscription (like in your snippet of code), it is not working because, when your code runs, you only sort the array once in the ngOnInit hook. By then, your observable hasn't emitted any userBirthday yet. So the usersBirthdayDate array is empty.

I'm not sure where/when you are trying to make you sort happen but have you tried something like the following:

```<code>this.usersSubscription = this.userService.birthdaySubject.subscribe(
    test => {
        this.usersBirthdayDate.push(test);
        this.usersBirthdayDate.sort(yourSortingFunction);
    }
);
</code>```

If that does not work maybe you could explain a bit more what happens in your subscription when you receive a new user? Then I'll be able to edit my answer if needed.

Body:
I'm struggling with rxjs.. I would like to sort an array coming from my subscription.
But the sort never play..
SO first I tried to display userBirthdayDate from service but didn't work like expected.

this is my service

 getAllUsers() {
    return new Promise((resolve, reject) => {
      firebase
        .database()
        .ref()
        .child('users')
        .on(
          'value',
          snapshot => {
            resolve(
              snapshot.forEach(childSnapshot => {
                this.usersBirthday = childSnapshot.val()
                  ? childSnapshot.val()
                  : [];
                this.emitBirthday();
              })
            );
          },
          error => {
            reject(error);
          }
        );
    });
  }

my component.ts

export class WidgetBirthdayComponent implements OnInit {
  users: User[];
  usersBirthdayDate = [];
  usersSubscription: Subscription;

  constructor(private userService: UsersService) {}

  ngOnInit() {
    // this.usersSubscription = this.userService.birthdaySubject.subscribe(
    //   test => {
    //     this.usersBirthdayDate.push(test);
    //   }
    // );
    // this.userService.emitBirthday();
    // this.userService.getAllUsers();

    const myArray = [
      {
        name: "Joel",
        birthdayDate: "Wednesday, November 25, 1992"
      },
      {
        name: "Sarah",
        birthdayDate: "Thursday, April 16, 1992"
      },
      {
        name: "Beverly",
        birthdayDate: "Thursday, February 26, 1998"
      }
    ];

    myArray.sort(function compare(a, b) {
      const now = new Date();
      const dateA = new Date(a.birthdayDate);
      dateA.setFullYear(now.getFullYear());
      if (dateA.getTime() - now.getTime() < 0) {
        dateA.setFullYear(now.getFullYear() + 1);
      }
      const dateB = new Date(b.birthdayDate);
      dateA.setFullYear(new Date().getFullYear());
      dateA.setFullYear(now.getFullYear());
      if (dateB.getTime() - now.getTime() < 0) {
        dateB.setFullYear(now.getFullYear() + 1);
      }
      return dateA.getTime() - dateB.getTime();
    });
    console.log(myArray);
  }

So I tried with strong data and my function sort is working well.. but I can"t use usersBirthdayDate[] on it.. PLease need help :)

Body:
In case you tried to sort the array outside the subscription (like in your snippet of code), it is not working because, when your code runs, you only sort the array once in the ngOnInit hook. By then, your observable hasn't emitted any userBirthday yet. So the usersBirthdayDate array is empty.

I'm not sure where/when you are trying to make you sort happen but have you tried something like the following:

this.usersSubscription = this.userService.birthdaySubject.subscribe(
    test => {
        this.usersBirthdayDate.push(test);
        this.usersBirthdayDate.sort(yourSortingFunction);
    }
);

If that does not work maybe you could explain a bit more what happens in your subscription when you receive a new user? Then I'll be able to edit my answer if needed.